File tree Expand file tree Collapse file tree 5 files changed +79
-4
lines changed
Expand file tree Collapse file tree 5 files changed +79
-4
lines changed Original file line number Diff line number Diff line change 1+ #include <stdlib.h>
2+ #include <string.h>
3+
4+ void main ()
5+ {
6+ char * data = nondet () ? NULL : malloc (8 );
7+ memset (data , 0 , 8 );
8+ memset (data , 0 , 8 );
9+ }
Original file line number Diff line number Diff line change 1+ CORE
2+ main.c
3+
4+ ^\[main.precondition_instance.1\] line .* memset destination region writeable: FAILURE$
5+ ^\[main.precondition_instance.2\] line .* memset destination region writeable: FAILURE$
6+ ^EXIT=10$
7+ ^SIGNAL=0$
8+ ^VERIFICATION FAILED$
9+ --
10+ --
11+ This test case checks that byte operations (e.g. memset) oninvalid and `NULL`
12+ pointers are correctly encoded in SMT2.
Original file line number Diff line number Diff line change 1+ #include <stdlib.h>
2+
3+ void main ()
4+ {
5+ assert (NULL != (NULL + 1 ));
6+ assert (NULL != (NULL - 1 ));
7+
8+ int offset ;
9+ __CPROVER_assume (offset != 0 );
10+ assert (NULL != (NULL + offset ));
11+
12+ assert (NULL - NULL == 0 );
13+
14+ int * ptr ;
15+ assert (ptr - NULL == 0 );
16+ ptr = NULL ;
17+ assert ((ptr - 1 ) + 1 == NULL );
18+
19+ ptr = nondet () ? NULL : malloc (1 );
20+ assert ((ptr - 1 ) + 1 == (NULL + 1 ) - 1 );
21+ }
Original file line number Diff line number Diff line change 1+ CORE
2+ main.c
3+
4+ ^\[main.assertion.1\] line .* assertion \(void \*\)0 != \(void \*\)0 \+ \(.*\)1: SUCCESS$
5+ ^\[main.assertion.2\] line .* assertion \(void \*\)0 != \(void \*\)0 - \(.*\)1: SUCCESS$
6+ ^\[main.assertion.3\] line .* assertion \(void \*\)0 != \(void \*\)0 \+ \(.*\)offset: SUCCESS$
7+ ^\[main.assertion.4\] line .* assertion \(void \*\)0 - \(void \*\)0 == \(.*\)0: SUCCESS$
8+ ^\[main.assertion.5\] line .* assertion ptr - \(void \*\)0 == \(.*\)0: FAILURE$
9+ ^\[main.assertion.6\] line .* assertion \(ptr - \(.*\)1\) \+ \(.*\)1 == \(\(.* \*\)NULL\): SUCCESS$
10+ ^\[main.assertion.7\] line .* assertion \(ptr - \(.*\)1\) \+ \(.*\)1 == \(\(.* \*\)NULL\): FAILURE$
11+ ^EXIT=10$
12+ ^SIGNAL=0$
13+ ^VERIFICATION FAILED$
14+ --
15+ --
16+ This test case checks that pointer arithmetic on NULL pointers are correctly
17+ encoded by the SMT2 translation routines.
Original file line number Diff line number Diff line change @@ -3175,18 +3175,29 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
31753175 p.type ().id () == ID_pointer,
31763176 " one of the operands should have pointer type" );
31773177
3178- const auto element_size = pointer_offset_size (expr.type ().subtype (), ns);
3179- CHECK_RETURN (element_size.has_value () && *element_size >= 1 );
3178+ mp_integer element_size;
3179+ if (expr.type ().subtype ().id () == ID_empty)
3180+ {
3181+ // This is a gcc extension.
3182+ // https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
3183+ element_size = 1 ;
3184+ }
3185+ else
3186+ {
3187+ auto element_size_opt = pointer_offset_size (expr.type ().subtype (), ns);
3188+ CHECK_RETURN (element_size_opt.has_value () && *element_size_opt >= 1 );
3189+ element_size = *element_size_opt;
3190+ }
31803191
31813192 out << " (bvadd " ;
31823193 convert_expr (p);
31833194 out << " " ;
31843195
3185- if (* element_size >= 2 )
3196+ if (element_size >= 2 )
31863197 {
31873198 out << " (bvmul " ;
31883199 convert_expr (i);
3189- out << " (_ bv" << * element_size << " " << boolbv_width (expr.type ())
3200+ out << " (_ bv" << element_size << " " << boolbv_width (expr.type ())
31903201 << " ))" ;
31913202 }
31923203 else
@@ -4249,6 +4260,11 @@ void smt2_convt::set_to(const exprt &expr, bool value)
42494260 if (expr.id () == ID_equal && value)
42504261 {
42514262 const equal_exprt &equal_expr=to_equal_expr (expr);
4263+ if (equal_expr.lhs ().type ().id () == ID_empty)
4264+ {
4265+ // ignore equality checking over expressions with empty (void) type
4266+ return ;
4267+ }
42524268
42534269 if (equal_expr.lhs ().id ()==ID_symbol)
42544270 {
You can’t perform that action at this time.
0 commit comments