Skip to content

Commit cdcba8f

Browse files
committed
make pointer_offset_exprt unsigned
This commit changes the type of __CPROVER_POINTER_OFFSET from ssize_t to size_t. To match, relational operators on pointers are now unsigned, to enable p+PTRDIFF_MAX+1 > p. The rationale is subtle. The ISO C 11 standard 6.5.8 par 5 suggests that a pair of pointers can be compared if either the pointers point into the object, or one beyond the end of the sequence. The behavior in the case of a pointer that points before the sequence is undefined. There is a similar narrative for pointer arithmetic. A pointer with an offset that has a set most significant bit should thus compare "less than" a pointer with an offset that has a zero MSB. This suggests an unsigned encoding.
1 parent f403924 commit cdcba8f

File tree

5 files changed

+16
-16
lines changed

5 files changed

+16
-16
lines changed

regression/cbmc-primitives/pointer-offset-01/test-no-cp.desc

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ main.c
33
--no-simplify --no-propagation
44
^EXIT=10$
55
^SIGNAL=0$
6-
\[main.assertion.1\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) >= 0: FAILURE
6+
\[main.assertion.1\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) >= 0: SUCCESS
77
\[main.assertion.2\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) < 0: FAILURE
88
--
99
^warning: ignoring
1010
--
11-
Check that both positive and negative offsets can be chosen for uninitialized
12-
pointers. We use --no-simplify and --no-propagation to ensure that the case is
13-
not solved by the constant propagation and thus tests the constraint encoding.
11+
Check that positive offsets can be chosen for uninitialized pointers. We
12+
use --no-simplify and --no-propagation to ensure that the case is not solved
13+
by the constant propagation and thus tests the constraint encoding.

regression/cbmc-primitives/pointer-offset-01/test.desc

+6-8
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ main.c
33

44
^EXIT=10$
55
^SIGNAL=0$
6-
\[main.assertion.1\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) >= 0: FAILURE
6+
\[main.assertion.1\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) >= 0: SUCCESS
77
\[main.assertion.2\] line \d+ assertion __CPROVER_POINTER_OFFSET\(p\) < 0: FAILURE
88
--
99
^warning: ignoring
1010
--
11-
For uninitialised pointers, CBMC chooses a nondeterministic value (though no memory
12-
is allocated). Since the offset of pointers is signed, negative offsets should be
13-
able to be chosen (along with positive ones) non-deterministically.
14-
`__CPROVER_POINTER_OFFSET` is the CBMC primitive that gets the pointer offset
15-
from the base address of the object. This test guards this, and especially
16-
against the case where we could only observe some cases where offsets were only
17-
positive (in some CI configurations, for instance).
11+
For uninitialised pointers, CBMC chooses a nondeterministic value (though no
12+
memory is allocated). Since the offset of pointers is unsigned, negative
13+
offsets cannot be chosen. `__CPROVER_POINTER_OFFSET` is the CBMC primitive
14+
that gets the pointer offset from the base address of the object. This test
15+
guards this.

regression/contracts/no_redudant_checks/test.desc

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ main.c
2323
^\[main.pointer_arithmetic.15\].*: SUCCESS
2424
^\[main.pointer_arithmetic.16\].*: SUCCESS
2525
^\[main.pointer_arithmetic.17\].*: SUCCESS
26-
^\*\* 0 of 20 failed \(1 iterations\)
26+
^\[main.pointer_arithmetic.18\].*: SUCCESS
27+
^\*\* 0 of 21 failed \(1 iterations\)
2728
^VERIFICATION SUCCESSFUL$
2829
--
2930
^\[main.overflow.\d+\].*: FAILURE
@@ -35,7 +36,7 @@ Checks that assertions generated by the first --pointer-overflow-check:
3536
We expect 20 assertions to be generated:
3637
In the goto-instrument run:
3738
- 2 for using malloc
38-
- 17 caused by --pointer-overflow-check
39+
- 18 caused by --pointer-overflow-check
3940

4041
In the final cbmc run:
4142
- 0 caused by --pointer-overflow-check

src/ansi-c/cprover_builtin_headers.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void __CPROVER_loop_entry(const void *);
4343

4444
// pointers
4545
__CPROVER_size_t __CPROVER_POINTER_OBJECT(const void *);
46-
__CPROVER_ssize_t __CPROVER_POINTER_OFFSET(const void *);
46+
__CPROVER_size_t __CPROVER_POINTER_OFFSET(const void *);
4747
__CPROVER_size_t __CPROVER_OBJECT_SIZE(const void *);
4848
__CPROVER_bool __CPROVER_DYNAMIC_OBJECT(const void *);
4949
void __CPROVER_allocated_memory(__CPROVER_size_t address, __CPROVER_size_t extent);

src/solvers/flattening/bv_pointers.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,14 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
195195
if(same_object_lit.is_false())
196196
return same_object_lit;
197197

198+
// The comparison is UNSIGNED, to match the type of pointer_offsett
198199
return prop.land(
199200
same_object_lit,
200201
bv_utils.rel(
201202
offset_bv0,
202203
expr.id(),
203204
offset_bv1,
204-
bv_utilst::representationt::SIGNED));
205+
bv_utilst::representationt::UNSIGNED));
205206
}
206207
}
207208

0 commit comments

Comments
 (0)