Skip to content

Commit 1689495

Browse files
committed
Track deallocated/dead in an array
This enables tracking of all deallocations and all dead objects, and thereby use of deallocated/dead_object predicates within assumptions.
1 parent 4e17a5d commit 1689495

File tree

13 files changed

+54
-37
lines changed

13 files changed

+54
-37
lines changed

regression/cbmc/array_of_bool_as_bitvec/test-smt2-outfile.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
CORE broken-smt-backend
22
main.c
33
--smt2 --outfile -
4-
\(= \(select array_of\.2 i\) \(ite false #b1 #b0\)\)
4+
\(= \(select array_of\.\d+ i\) \(ite false #b1 #b0\)\)
55
\(= \(select array\.3 \(\(_ zero_extend 32\) \|main::1::idx!0@1#1\|\)\) #b1\)
66
\(= \(select array\.3 \(_ bv\d+ 64\)\) \(ite false #b1 #b0\)\)
77
^EXIT=0$
88
^SIGNAL=0$
99
--
10-
\(= \(select array_of\.2 i\) false\)
10+
\(= \(select array_of\.\d+ i\) false\)
1111
\(= \(select array\.3 \(\(_ zero_extend 32\) \|main::1::idx!0@1#1\|\)\) #b1 #b0\)
1212
\(= \(select array\.3 \(_ bv\d+ 64\)\) false\)
1313
--

regression/cbmc/pointer-extra-checks/test.desc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ main.c
1010
^\[main.pointer_dereference.5\] .* dereference failure: pointer outside dynamic object bounds in \*r: SUCCESS$
1111
^\[main.pointer_dereference.6\] .* dereference failure: pointer NULL in \*s: FAILURE$
1212
^\[main.pointer_dereference.7\] .* dereference failure: pointer invalid in \*s: FAILURE$
13-
^\[main.pointer_dereference.8\] .* dereference failure: deallocated dynamic object in \*s: FAILURE$
1413
^\[main.pointer_dereference.9\] .* dereference failure: dead object in \*s: FAILURE$
1514
^\[main.pointer_dereference.10\] .* dereference failure: pointer outside object bounds in \*s: FAILURE$
1615
^\[main.pointer_dereference.11\] .* dereference failure: invalid integer address in \*s: FAILURE$

regression/cbmc/r_w_ok10/main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <stdlib.h>
2+
3+
int main()
4+
{
5+
int *p = malloc(sizeof(int));
6+
free(p);
7+
__CPROVER_assume(__CPROVER_r_ok(p, sizeof(int)));
8+
__CPROVER_assert(0, "should be unreachable");
9+
}

regression/cbmc/r_w_ok10/test.desc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
4+
VERIFICATION SUCCESSFUL
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
10+
This test checks that __CPROVER_r_ok can safely be used in assumptions.

regression/cbmc/realloc-should-not-free-on-failure-to-allocate/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
test.c
33
--malloc-may-fail --malloc-fail-null
4-
^\[main.precondition_instance.\d+] line \d+ double free: SUCCESS$
4+
^\[(free.precondition|main.precondition_instance).\d+] line \d+ double free: SUCCESS$
55
^VERIFICATION SUCCESSFUL$
66
^EXIT=0$
77
^SIGNAL=0$

src/ansi-c/ansi_c_internal_additions.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,10 @@ void ansi_c_internal_additions(std::string &code)
171171
CPROVER_PREFIX "constant_infinity_uint];\n"
172172

173173
// malloc
174-
"const void *" CPROVER_PREFIX "deallocated=0;\n"
175-
"const void *" CPROVER_PREFIX "dead_object=0;\n"
174+
CPROVER_PREFIX "bool " CPROVER_PREFIX "deallocated["
175+
CPROVER_PREFIX "constant_infinity_uint];\n"
176+
CPROVER_PREFIX "bool " CPROVER_PREFIX "dead_object["
177+
CPROVER_PREFIX "constant_infinity_uint];\n"
176178
"const void *" CPROVER_PREFIX "new_object=0;\n" // for C++
177179
CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_is_new_array=0;\n" // for C++
178180
"const void *" CPROVER_PREFIX "memory_leak=0;\n"

src/ansi-c/goto_check_c.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,15 +2214,9 @@ void goto_check_ct::goto_check(
22142214
if(local_bitvector_analysis->dirty(variable))
22152215
{
22162216
// need to mark the dead variable as dead
2217-
exprt lhs = ns.lookup(CPROVER_PREFIX "dead_object").symbol_expr();
2218-
exprt address_of_expr = typecast_exprt::conditional_cast(
2219-
address_of_exprt(variable), lhs.type());
2220-
if_exprt rhs(
2221-
side_effect_expr_nondett(bool_typet(), i.source_location()),
2222-
std::move(address_of_expr),
2223-
lhs);
2217+
exprt lhs = dead_object(address_of_exprt{variable}, ns);
22242218
new_code.add(goto_programt::make_assignment(
2225-
code_assignt{std::move(lhs), std::move(rhs), i.source_location()},
2219+
code_assignt{std::move(lhs), true_exprt{}, i.source_location()},
22262220
i.source_location()));
22272221
}
22282222
}

src/ansi-c/library/cprover.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef signed long long __CPROVER_ssize_t;
2020

2121
void *__CPROVER_allocate(__CPROVER_size_t size, __CPROVER_bool zero);
2222
void __CPROVER_deallocate(void *);
23-
extern const void *__CPROVER_deallocated;
23+
extern __CPROVER_bool __CPROVER_deallocated[];
2424
extern const void *__CPROVER_new_object;
2525
extern __CPROVER_bool __CPROVER_malloc_is_new_array;
2626
extern const void *__CPROVER_memory_leak;

src/ansi-c/library/stdlib.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ void free(void *ptr)
264264
"free argument has offset zero");
265265

266266
// catch double free
267-
__CPROVER_precondition(ptr==0 || __CPROVER_deallocated!=ptr,
268-
"double free");
267+
__CPROVER_precondition(
268+
ptr == 0 || !__CPROVER_deallocated[__CPROVER_POINTER_OBJECT(ptr)],
269+
"double free");
269270

270271
// catch people who try to use free(...) for stuff
271272
// allocated with new[]
@@ -602,10 +603,7 @@ __CPROVER_HIDE:;
602603

603604
/* FUNCTION: __CPROVER_deallocate */
604605

605-
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
606-
607606
void __CPROVER_deallocate(void *ptr)
608607
{
609-
if(__VERIFIER_nondet___CPROVER_bool())
610-
__CPROVER_deallocated = ptr;
608+
__CPROVER_deallocated[__CPROVER_POINTER_OBJECT(ptr)] = 1;
611609
}

src/cpp/cpp_internal_additions.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,12 @@ void cpp_internal_additions(std::ostream &out)
8888
<< CPROVER_PREFIX "memory[__CPROVER::constant_infinity_uint];" << '\n';
8989

9090
// malloc
91-
out << "const void *" CPROVER_PREFIX "deallocated = 0;" << '\n';
92-
out << "const void *" CPROVER_PREFIX "dead_object = 0;" << '\n';
91+
out << CPROVER_PREFIX "bool "
92+
<< CPROVER_PREFIX "deallocated[__CPROVER::constant_infinity_uint];"
93+
<< '\n';
94+
out << CPROVER_PREFIX "bool "
95+
<< CPROVER_PREFIX "dead_object[__CPROVER::constant_infinity_uint];"
96+
<< '\n';
9397
out << "const void *" CPROVER_PREFIX "new_object = 0;" << '\n';
9498
out << "" CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_is_new_array = 0;"
9599
<< '\n';

0 commit comments

Comments
 (0)