Skip to content

Overwriting a composite object in an array causes a blowup in variables #3311

@jsalzbergedu

Description

@jsalzbergedu

The following code:

const MAX_NUM_OBJECTS: usize = 1024;
const MAX_OBJECT_SIZE: usize = 64;
const STACK_DEPTH: usize = 6;


type PtrId = u32;

#[derive(Copy, Clone)]
enum Item {
    Even,
    Odd,
}

#[kani::proof]
fn main() {
    let mut local = 5;
    let local_ptr = &local as *const i32;
    let ptr_object = kani::mem::pointer_object(local_ptr);
    let ptr_offset = kani::mem::pointer_offset(local_ptr);
    let mut mem: [[Option<[Item; 10]>; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS] =
                 [[None; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS];
    let mut s = match mem[ptr_object][ptr_offset] {
        None => [Item::Even; 10],
        Some(v) => v
    };
    s[0] = Item::Odd;
    mem[ptr_object][ptr_offset] = Some(s);
}

Produces a SAT instance with millions of variables when run by Kani. Changing the pointer object to a constant reduces the size to roughly 100 variables:

const MAX_NUM_OBJECTS: usize = 1024;
const MAX_OBJECT_SIZE: usize = 64;
const STACK_DEPTH: usize = 6;


type PtrId = u32;

#[derive(Copy, Clone)]
enum Item {
    Even,
    Odd,
}

#[kani::proof]
fn main() {
    let mut local = 5;
    let local_ptr = &local as *const i32;
    let ptr_object = kani::mem::pointer_object(local_ptr);
    let ptr_offset = kani::mem::pointer_offset(local_ptr);
    let mut mem: [[Option<[Item; 10]>; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS] =
                 [[None; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS];
    let mut s = match mem[0][ptr_offset] {
        None => [Item::Even; 10],
        Some(v) => v
    };
    s[0] = Item::Odd;
    mem[0][ptr_offset] = Some(s);
}

and swapping out for a triple array also has a reasonable verification size

const MAX_NUM_OBJECTS: usize = 1024;
const MAX_OBJECT_SIZE: usize = 64;
const STACK_DEPTH: usize = 6;


type PtrId = u32;

#[derive(Copy, Clone)]
enum Item {
    Even,
    Odd,
}

#[kani::proof]
fn main() {
    let mut local = 5;
    let local_ptr = &local as *const i32;
    let ptr_object = kani::mem::pointer_object(local_ptr);
    let ptr_offset = kani::mem::pointer_offset(local_ptr);
    let mut mem: [[[Item; 10]; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS] =
                 [[[Item::Even; 10]; MAX_OBJECT_SIZE]; MAX_NUM_OBJECTS];
    mem[ptr_object][ptr_offset][0] = Item::Odd;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-CBMCIssue related to an existing CBMC issue[E] PerformanceTrack performance improvement (Time / Memory / CPU)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions