-
Notifications
You must be signed in to change notification settings - Fork 273
Add tests to check semantics of pointer primitives #5324
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
Add tests to check semantics of pointer primitives #5324
Conversation
danpoe
commented
Apr 27, 2020
•
edited
Loading
edited
- Each commit message has a non-empty body, explaining why the change was made.
- n/a Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
- n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
- Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
- n/a My commit message includes data points confirming performance improvements (if claimed).
- My PR is restricted to a single feature or bugfix.
- n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.
828ace9
to
04a8998
Compare
-- | ||
^warning: ignoring | ||
-- | ||
Check that uninitialized pointers are not considered pointing to dynamic objects |
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.
Is this what we want? Or should it be non-det whether this is true?
In particular, is there a doc where all these expectations are laid out?
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 think I agree with @danielsn, though I'm not clear what I as a user am trying to get out asserting on this property. But in general, seems safest for it to fail if you assert either way (in my mental model - you're asserting on UB, so whatever you assert, it should be false)
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.
@thk123 cbmc doesn't necessarily behave like that on UB. In general, one needs the appropriate check flags to be enabled to catch certain cases. For example, signed integer overflow is UB, though one needs to enable --signed-overflow-check
to catch that case. Otherwise, the values will just wrap around.
In general though, I think it's a good idea for operations to be nondet in such cases as far as possible. So yes, I've changed the test to check for both the negated and the non-negated condition, and have specified that both should fail in the test.desc file.
-- | ||
^warning: ignoring | ||
-- | ||
Check that __CPROVER_same_object() is true when given a pointer variable, and an |
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 it be worth it check that an offset into the object also maintains the same object property?
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.
Added
-- | ||
^warning: ignoring | ||
-- | ||
Check that __CPROVER_same_object() is false when given two pointers, with one |
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.
Is that expected? malloc is allowed to (and often does) reuse objects
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 think this depends on how you plan to use _same_object
? assert(same_object(p1, p2)
certainly must fail. I think since this is an internal, it should be more exact, in this case, we know they are not the same object, they are the result of two separate mallocs. However, I would expect assert(p1 != p2)
to fail, since is possible they could have the same address since the memory has been freed.
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.
Yes, assert(p1 != p2)
should fail, though currently the way malloc
is modelled in cbmc it doesn't reuse addresses.
My overall question: is there a doc explaining the expected semantics of each primitive? When given a reference to (list not necessarily complete)
|
Also, what happens if we semi-constrain a variable? e.g.
|
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.
Looks good - I think we need to check some of them are actually havoicing by adding asserts for either direction
-- | ||
^warning: ignoring | ||
-- | ||
Check that uninitialized pointers are not considered pointing to dynamic objects |
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 think I agree with @danielsn, though I'm not clear what I as a user am trying to get out asserting on this property. But in general, seems safest for it to fail if you assert either way (in my mental model - you're asserting on UB, so whatever you assert, it should be false)
-- | ||
^warning: ignoring | ||
-- | ||
Check that __CPROVER_same_object() is false when given two pointers, with one |
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 think this depends on how you plan to use _same_object
? assert(same_object(p1, p2)
certainly must fail. I think since this is an internal, it should be more exact, in this case, we know they are not the same object, they are the result of two separate mallocs. However, I would expect assert(p1 != p2)
to fail, since is possible they could have the same address since the memory has been freed.
305ed1f
to
ac5c944
Compare
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.
Thanks seems good (clang-format is complaining on travis)
ac5c944
to
175d74f
Compare