Skip to content

Make __CPROVER_allocated_memory work with non-POD type objects #3595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions regression/cbmc/union12/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
typedef struct
{
union {
int access[256];
};
} S1;

typedef struct
{
int c;
} S2;

static S1(*const l[1]) = {((S1 *)((0x50000000UL) + 0x00000))};

void main()
{
__CPROVER_allocated_memory(0x50000000UL, sizeof(S1));
l[0]->access[0] = 0;
__CPROVER_assert(l[0]->access[0] == 0, "holds");
__CPROVER_assert(l[0]->access[1] == 0, "should fail");
__CPROVER_allocated_memory(0x40000000UL + 0x40000, sizeof(S2));
((S2 *)((0x40000000UL) + 0x40000))->c = 0x0707;
}
15 changes: 15 additions & 0 deletions regression/cbmc/union12/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CORE
main.c
--pointer-check
^EXIT=10$
^SIGNAL=0$
^\[main\.assertion\.2\] line 20 should fail: FAILURE$
^\*\* 1 of 17 failed
^VERIFICATION FAILED$
--
^warning: ignoring
--
Despite the large array inside the union, the test should complete within 10
seconds. Simplify extractbits(concatenation(...)) is essential to make this
possible. With 77236cc34 (Avoid nesting of ID_with/byte_update by rewriting
byte_extract to use the root object) the test already is trivial, however.
1 change: 1 addition & 0 deletions scripts/delete_failing_smt2_solver_tests
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ rm struct7/test.desc
rm struct9/test.desc
rm trace-values/trace-values.desc
rm trace_show_function_calls/test.desc
rm union12/test.desc
rm union6/test.desc
rm union7/test.desc
rm union9/test.desc
Expand Down
35 changes: 27 additions & 8 deletions src/analyses/goto_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -992,12 +992,16 @@ goto_checkt::address_check(const exprt &address, const exprt &size)
alloc_disjuncts.push_back(and_exprt(lb_check, ub_check));
}

const exprt allocs = disjunction(alloc_disjuncts);
const exprt in_bounds_of_some_explicit_allocation =
disjunction(alloc_disjuncts);

if(flags.is_unknown() || flags.is_null())
{
conditions.push_back(conditiont(
or_exprt(allocs, not_exprt(null_pointer(address))), "pointer NULL"));
or_exprt(
in_bounds_of_some_explicit_allocation,
not_exprt(null_pointer(address))),
"pointer NULL"));
}

if(flags.is_unknown())
Expand All @@ -1010,21 +1014,28 @@ goto_checkt::address_check(const exprt &address, const exprt &size)
if(flags.is_uninitialized())
{
conditions.push_back(conditiont(
or_exprt(allocs, not_exprt(invalid_pointer(address))),
or_exprt(
in_bounds_of_some_explicit_allocation,
not_exprt(invalid_pointer(address))),
"pointer uninitialized"));
}

if(flags.is_unknown() || flags.is_dynamic_heap())
{
conditions.push_back(conditiont(
not_exprt(deallocated(address, ns)),
or_exprt(
in_bounds_of_some_explicit_allocation,
not_exprt(deallocated(address, ns))),
"deallocated dynamic object"));
}

if(flags.is_unknown() || flags.is_dynamic_local())
{
conditions.push_back(conditiont(
not_exprt(dead_object(address, ns)), "dead object"));
or_exprt(
in_bounds_of_some_explicit_allocation,
not_exprt(dead_object(address, ns))),
"dead object"));
}

if(flags.is_unknown() || flags.is_dynamic_heap())
Expand All @@ -1034,7 +1045,10 @@ goto_checkt::address_check(const exprt &address, const exprt &size)
dynamic_object_upper_bound(address, ns, size));

conditions.push_back(conditiont(
implies_exprt(malloc_object(address, ns), not_exprt(dynamic_bounds_violation)),
or_exprt(
in_bounds_of_some_explicit_allocation,
implies_exprt(
malloc_object(address, ns), not_exprt(dynamic_bounds_violation))),
"pointer outside dynamic object bounds"));
}

Expand All @@ -1047,14 +1061,19 @@ goto_checkt::address_check(const exprt &address, const exprt &size)
object_upper_bound(address, ns, size));

conditions.push_back(conditiont(
implies_exprt(not_exprt(dynamic_object(address)), not_exprt(object_bounds_violation)),
or_exprt(
in_bounds_of_some_explicit_allocation,
implies_exprt(
not_exprt(dynamic_object(address)),
not_exprt(object_bounds_violation))),
"pointer outside object bounds"));
}

if(flags.is_unknown() || flags.is_integer_address())
{
conditions.push_back(conditiont(
implies_exprt(integer_address(address), allocs),
implies_exprt(
integer_address(address), in_bounds_of_some_explicit_allocation),
"invalid integer address"));
}

Expand Down