-
Notifications
You must be signed in to change notification settings - Fork 284
Fix pointer subtraction semantics #5838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c12b057 to
d5b099e
Compare
|
While at it, if both pointers are null, the result should also be nondeterministic. |
Codecov Report
@@ Coverage Diff @@
## develop #5838 +/- ##
========================================
Coverage 72.86% 72.87%
========================================
Files 1421 1421
Lines 154173 154207 +34
========================================
+ Hits 112337 112371 +34
Misses 41836 41836
Continue to review full report at Codecov.
|
More generally, I believe this should be the case whenever pointers aren't valid, unless just one byte (or element?) beyond the object? |
martin-cs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can add the tests it would be nice.
|
|
||
| int diff = array - other_array; | ||
| _Bool nondet; | ||
| if(nondet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this test for non-determinism.
| int other_array[2]; | ||
|
|
||
| __CPROVER_assert(&array[0] - &array[2] == -2, "correct"); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would I be awful to request...
__CPROVER_assert(((char *)(&array[3])) - ((char *)(&array[1])) == 2*sizeof(int), "casting works");
and
int *p = &array[3];
++p;
__CPROVER_assert(p - &array[0] == 4, "end plus one works");
__CPROVER_assert(p - &array[0] != 3, "end plus one works");
++p;
_Bool nondet_branch;
if (nondet_branch)
__CPROVER_assert(p - &array[0] == 5, "end plus 2 is nondet");
else
__CPROVER_assert(p - &array[0] != 5, "end plus 2 is nondet");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
goto_checkt::pointer_rel_check returns early when enable_pointer_check is false, there is no need to test this again.
d5b099e to
7c8b5ea
Compare
Subtracting pointers not pointing into the same (array) object (or one byte past the object) is undefined behaviour.
Subtracting pointers over the same object is subtraction of the offset (divided by the element size). Subtracting pointers over different objects should yield a non-deterministic result.
7c8b5ea to
5b8028a
Compare
That's now covered, which required fixing one of our regression tests... |
(Please review commit-by-commit.)
Subtracting pointers over the same object is subtraction of the offset
(divided by the element size). Subtracting pointers over different
objects should yield a non-deterministic result.