Skip to content

Commit eade886

Browse files
committed
Pointer subtraction in back-end: no need for bounds checking
5b8028a added pointer validity checks in the back-end when performing pointer minus pointer operations. Given our pointer encoding it seems important to do a same-object test as, for distinct objects, the object identifier part would start to play into the subtraction. When operating on the same object, however, even out-of-bounds pointers' subtraction should be indistinguishable from how this works on actual hardware. Therefore, this commit removes the bounds-checking part. (C semantics have a pointer-validity requirement, and we catch this via checks inserted in the front-end as the regression test demonstrates. We do not need to catch this in the back-end.)
1 parent beebdda commit eade886

File tree

2 files changed

+5
-36
lines changed

2 files changed

+5
-36
lines changed

regression/cbmc/Pointer_difference2/test.desc

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ main.c
55
^\[main.pointer.1\] line 8 same object violation in array - other_array: FAILURE$
66
^\[main.assertion.2\] line 11 undefined behavior: FAILURE$
77
^\[main.assertion.3\] line 13 undefined behavior: FAILURE$
8-
^\[main.assertion.7\] line 26 end plus 2 is nondet: FAILURE$
8+
^\[main.assertion.7\] line 26 end plus 2 is nondet: (UNKNOWN|FAILURE)$
99
^\[main.pointer_arithmetic.\d+\] line 26 pointer relation: pointer outside object bounds in p: FAILURE$
10-
^\[main.assertion.8\] line 28 end plus 2 is nondet: FAILURE$
10+
^\[main.assertion.8\] line 28 end plus 2 is nondet: (UNKNOWN|FAILURE)$
1111
^\[main.pointer_arithmetic.\d+\] line 28 pointer relation: pointer outside object bounds in p: FAILURE$
12-
^\*\* 9 of \d+ failed
12+
^\*\* [789] of \d+ failed
1313
^VERIFICATION FAILED$
1414
^EXIT=10$
1515
^SIGNAL=0$

src/solvers/flattening/bv_pointers.cpp

+2-33
Original file line numberDiff line numberDiff line change
@@ -665,39 +665,8 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
665665
difference, element_size_bv, bv_utilst::representationt::SIGNED);
666666
}
667667

668-
// test for null object (integer constants)
669-
const exprt null_object = ::null_object(minus_expr.lhs());
670-
literalt in_bounds = convert(null_object);
671-
672-
if(!in_bounds.is_true())
673-
{
674-
// compute the object size (again, possibly using cached results)
675-
const exprt object_size = ::object_size(minus_expr.lhs());
676-
const bvt object_size_bv =
677-
bv_utils.zero_extension(convert_bv(object_size), width);
678-
679-
const literalt lhs_in_bounds = prop.land(
680-
!bv_utils.sign_bit(lhs_offset),
681-
bv_utils.rel(
682-
lhs_offset,
683-
ID_le,
684-
object_size_bv,
685-
bv_utilst::representationt::UNSIGNED));
686-
687-
const literalt rhs_in_bounds = prop.land(
688-
!bv_utils.sign_bit(rhs_offset),
689-
bv_utils.rel(
690-
rhs_offset,
691-
ID_le,
692-
object_size_bv,
693-
bv_utilst::representationt::UNSIGNED));
694-
695-
in_bounds =
696-
prop.lor(in_bounds, prop.land(lhs_in_bounds, rhs_in_bounds));
697-
}
698-
699-
prop.l_set_to_true(prop.limplies(
700-
prop.land(same_object_lit, in_bounds), bv_utils.equal(difference, bv)));
668+
prop.l_set_to_true(
669+
prop.limplies(same_object_lit, bv_utils.equal(difference, bv)));
701670
}
702671

703672
return bv;

0 commit comments

Comments
 (0)