Skip to content

Commit 0edf9a5

Browse files
committed
[smt2_convt] Fix arithmetic on invalid pointers
CBMC crashed on SMT2 conversion of pointer arithmetic on NULL and other kinds of invalid pointers. This change fixes the encoding of pointer arithmetic on invalid pointers.
1 parent 5914d75 commit 0edf9a5

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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.

src/solvers/smt2/smt2_conv.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,18 +3162,29 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
31623162
p.type().id() == ID_pointer,
31633163
"one of the operands should have pointer type");
31643164

3165-
const auto element_size = pointer_offset_size(expr.type().subtype(), ns);
3166-
CHECK_RETURN(element_size.has_value() && *element_size >= 1);
3165+
mp_integer element_size;
3166+
if(expr.type().subtype().id() == ID_empty)
3167+
{
3168+
// This is a gcc extension.
3169+
// https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
3170+
element_size = 1;
3171+
}
3172+
else
3173+
{
3174+
auto element_size_opt = pointer_offset_size(expr.type().subtype(), ns);
3175+
CHECK_RETURN(element_size_opt.has_value() && *element_size_opt >= 1);
3176+
element_size = *element_size_opt;
3177+
}
31673178

31683179
out << "(bvadd ";
31693180
convert_expr(p);
31703181
out << " ";
31713182

3172-
if(*element_size >= 2)
3183+
if(element_size >= 2)
31733184
{
31743185
out << "(bvmul ";
31753186
convert_expr(i);
3176-
out << " (_ bv" << *element_size << " " << boolbv_width(expr.type())
3187+
out << " (_ bv" << element_size << " " << boolbv_width(expr.type())
31773188
<< "))";
31783189
}
31793190
else

0 commit comments

Comments
 (0)