Skip to content

Commit 4b0a5c2

Browse files
committed
Replace __CPROVER_malloc_is_new_array by an uninterpreted function
With this encoding we no longer non-deterministically track just one such array. This enables the use in assumptions. Also, we will only incur a cost in the encoding when actually using new/delete instead of always having a global variable, even when unused.
1 parent 99e3fcd commit 4b0a5c2

File tree

6 files changed

+13
-24
lines changed

6 files changed

+13
-24
lines changed

src/ansi-c/ansi_c_internal_additions.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ void ansi_c_internal_additions(std::string &code)
179179
"const void *" CPROVER_PREFIX "deallocated=0;\n"
180180
"const void *" CPROVER_PREFIX "dead_object=0;\n"
181181
"const void *" CPROVER_PREFIX "new_object=0;\n" // for C++
182-
CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_is_new_array=0;\n" // for C++
183182
"const void *" CPROVER_PREFIX "memory_leak=0;\n"
184183
"void *" CPROVER_PREFIX "allocate("
185184
CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"

src/ansi-c/library/cprover.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ typedef __typeof__(sizeof(int)) __CPROVER_size_t;
1313
void *__CPROVER_allocate(__CPROVER_size_t size, __CPROVER_bool zero);
1414
extern const void *__CPROVER_deallocated;
1515
extern const void *__CPROVER_new_object;
16-
extern _Bool __CPROVER_malloc_is_new_array;
1716
extern const void *__CPROVER_memory_leak;
1817

1918
extern int __CPROVER_malloc_failure_mode;

src/ansi-c/library/stdlib.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,6 @@ __CPROVER_HIDE:;
109109
__CPROVER_deallocated =
110110
(malloc_res == __CPROVER_deallocated) ? 0 : __CPROVER_deallocated;
111111

112-
// record the object size for non-determistic bounds checking
113-
__CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool();
114-
__CPROVER_malloc_is_new_array =
115-
record_malloc ? 0 : __CPROVER_malloc_is_new_array;
116-
117112
// detect memory leaks
118113
__CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool();
119114
__CPROVER_memory_leak = record_may_leak ? malloc_res : __CPROVER_memory_leak;
@@ -171,11 +166,6 @@ __CPROVER_HIDE:;
171166
__CPROVER_deallocated =
172167
(malloc_res == __CPROVER_deallocated) ? 0 : __CPROVER_deallocated;
173168

174-
// record the object size for non-determistic bounds checking
175-
__CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool();
176-
__CPROVER_malloc_is_new_array =
177-
record_malloc ? 0 : __CPROVER_malloc_is_new_array;
178-
179169
// detect memory leaks
180170
__CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool();
181171
__CPROVER_memory_leak = record_may_leak ? malloc_res : __CPROVER_memory_leak;
@@ -201,10 +191,6 @@ inline void *__builtin_alloca(__CPROVER_size_t alloca_size)
201191
// make sure it's not recorded as deallocated
202192
__CPROVER_deallocated=(res==__CPROVER_deallocated)?0:__CPROVER_deallocated;
203193

204-
// record the object size for non-determistic bounds checking
205-
__CPROVER_bool record_malloc=__VERIFIER_nondet___CPROVER_bool();
206-
__CPROVER_malloc_is_new_array=record_malloc?0:__CPROVER_malloc_is_new_array;
207-
208194
// record alloca to detect invalid free
209195
__CPROVER_bool record_alloca = __VERIFIER_nondet___CPROVER_bool();
210196
__CPROVER_alloca_object = record_alloca ? res : __CPROVER_alloca_object;
@@ -233,6 +219,7 @@ __CPROVER_HIDE:;
233219
#undef free
234220

235221
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
222+
__CPROVER_bool __CPROVER_uninterpreted_is_new_array(const void *);
236223
extern void *__CPROVER_alloca_object;
237224

238225
inline void free(void *ptr)
@@ -254,7 +241,8 @@ inline void free(void *ptr)
254241
// catch people who try to use free(...) for stuff
255242
// allocated with new[]
256243
__CPROVER_precondition(
257-
ptr == 0 || __CPROVER_new_object != ptr || !__CPROVER_malloc_is_new_array,
244+
ptr == 0 || __CPROVER_new_object != ptr ||
245+
!__CPROVER_uninterpreted_is_new_array(ptr),
258246
"free called for new[] object");
259247

260248
// catch people who try to use free(...) with alloca

src/cpp/cpp_internal_additions.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ void cpp_internal_additions(std::ostream &out)
9191
out << "const void *" CPROVER_PREFIX "deallocated = 0;" << '\n';
9292
out << "const void *" CPROVER_PREFIX "dead_object = 0;" << '\n';
9393
out << "const void *" CPROVER_PREFIX "new_object = 0;" << '\n';
94-
out << "" CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_is_new_array = 0;"
95-
<< '\n';
9694
out << "const void *" CPROVER_PREFIX "memory_leak = 0;" << '\n';
9795
out << "void *" CPROVER_PREFIX "allocate("
9896
<< CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);" << '\n';

src/cpp/library/cprover.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ typedef __typeof__(sizeof(int)) __CPROVER_size_t;
1414
void *__CPROVER_allocate(__CPROVER_size_t size, __CPROVER_bool zero);
1515
extern const void *__CPROVER_deallocated;
1616
extern const void *__CPROVER_new_object;
17-
extern _Bool __CPROVER_malloc_is_new_array;
1817
extern const void *__CPROVER_memory_leak;
1918

2019
void __CPROVER_assume(__CPROVER_bool assumption) __attribute__((__noreturn__));

src/cpp/library/new.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* FUNCTION: __new */
22

33
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
4+
__CPROVER_bool __CPROVER_uninterpreted_is_new_array(const void *);
45

56
inline void *__new(__typeof__(sizeof(int)) malloc_size)
67
{
@@ -16,7 +17,7 @@ inline void *__new(__typeof__(sizeof(int)) malloc_size)
1617
// non-deterministically record the object for delete/delete[] checking
1718
__CPROVER_bool record_malloc=__VERIFIER_nondet___CPROVER_bool();
1819
__CPROVER_new_object = record_malloc ? res : __CPROVER_new_object;
19-
__CPROVER_malloc_is_new_array=record_malloc?0:__CPROVER_malloc_is_new_array;
20+
__CPROVER_assume(!__CPROVER_uninterpreted_is_new_array(res));
2021

2122
// detect memory leaks
2223
__CPROVER_bool record_may_leak=__VERIFIER_nondet___CPROVER_bool();
@@ -28,6 +29,7 @@ inline void *__new(__typeof__(sizeof(int)) malloc_size)
2829
/* FUNCTION: __new_array */
2930

3031
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
32+
__CPROVER_bool __CPROVER_uninterpreted_is_new_array(const void *);
3133

3234
inline void *__new_array(__CPROVER_size_t count, __CPROVER_size_t size)
3335
{
@@ -43,7 +45,7 @@ inline void *__new_array(__CPROVER_size_t count, __CPROVER_size_t size)
4345
// non-deterministically record the object for delete/delete[] checking
4446
__CPROVER_bool record_malloc=__VERIFIER_nondet___CPROVER_bool();
4547
__CPROVER_new_object = record_malloc ? res : __CPROVER_new_object;
46-
__CPROVER_malloc_is_new_array=record_malloc?1:__CPROVER_malloc_is_new_array;
48+
__CPROVER_assume(__CPROVER_uninterpreted_is_new_array(res));
4749

4850
// detect memory leaks
4951
__CPROVER_bool record_may_leak=__VERIFIER_nondet___CPROVER_bool();
@@ -66,6 +68,7 @@ inline void *__placement_new(__typeof__(sizeof(int)) malloc_size, void *p)
6668
/* FUNCTION: __delete */
6769

6870
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
71+
__CPROVER_bool __CPROVER_uninterpreted_is_new_array(const void *);
6972

7073
inline void __delete(void *ptr)
7174
{
@@ -81,7 +84,8 @@ inline void __delete(void *ptr)
8184

8285
// catch people who call delete for objects allocated with new[]
8386
__CPROVER_precondition(
84-
ptr == 0 || __CPROVER_new_object != ptr || !__CPROVER_malloc_is_new_array,
87+
ptr == 0 || __CPROVER_new_object != ptr ||
88+
!__CPROVER_uninterpreted_is_new_array(ptr),
8589
"delete of array object");
8690

8791
// If ptr is NULL, no operation is performed.
@@ -101,6 +105,7 @@ inline void __delete(void *ptr)
101105
/* FUNCTION: __delete_array */
102106

103107
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
108+
__CPROVER_bool __CPROVER_uninterpreted_is_new_array(const void *);
104109

105110
inline void __delete_array(void *ptr)
106111
{
@@ -120,7 +125,8 @@ inline void __delete_array(void *ptr)
120125

121126
// catch people who call delete[] for objects allocated with new
122127
__CPROVER_precondition(
123-
ptr == 0 || __CPROVER_new_object != ptr || __CPROVER_malloc_is_new_array,
128+
ptr == 0 || __CPROVER_new_object != ptr ||
129+
__CPROVER_uninterpreted_is_new_array(ptr),
124130
"delete[] of non-array object");
125131

126132
if(ptr!=0)

0 commit comments

Comments
 (0)