-
Notifications
You must be signed in to change notification settings - Fork 285
add check for INT_MIN % -1 #3689
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
kroening
commented
Jan 5, 2019
- Each commit message has a non-empty body, explaining why the change was made.
- Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
- 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.
allredj
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 7a9bf12).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/96374454
tautschnig
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.
I think the output generated is misleading, as this isn't specific to int (and thus INT_MIN). The C standard states "If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined." So it's equally undefined for any type wider than int.
And what about other languages? The commit message explicitly states that this is not undefined in C++, and I have no idea about Java.
7a9bf12 to
2f5d670
Compare
|
I've changed the message to "result of signed mod is not representable". It's defined in C++, but crashes anyway with any compiler I tried. It's guaranteed to be 0 in Java (and I tried that this actually works, at least with openjdk 10). |
2f5d670 to
de08db4
Compare
allredj
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.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: 2f5d670).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/96381014
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
allredj
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: de08db4).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/96381185
| /// check a mod expression for the case INT_MIN % -1 | ||
| void goto_checkt::mod_overflow_check(const mod_exprt &expr, const guardt &guard) | ||
| { | ||
| if(!enable_signed_overflow_check) |
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(!enable_signed_overflow_check || mode == ID_java) based on the conversation.
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.
ok
src/analyses/goto_check.cpp
Outdated
| guard); | ||
| } | ||
|
|
||
| return; |
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.
Seems unnecessary?
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.
removed
| expr.op0(), to_signedbv_type(type).smallest_expr()); | ||
|
|
||
| notequal_exprt minus_one_neq( | ||
| expr.op1(), from_integer(-1, expr.op1().type())); |
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.
What I still don't like very much are the number of further assumptions baked into this. The standard says that a / b must be representable. Only because of two's complement does this imply that this isn't representable exactly for the case of b == -1. I'm not sure we have ever specified that two's complement is the one and only representation for goto programs to use? Shouldn't we do what the standard says, and simply check for overflow of a / b?
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.
C11 and C++11 also allow one's complement and the signed magnitude representation. But then the test type.id() == ID_signedbv would fail (this is documented to be two's complement).
Note that the check for overflow of signed integer division is implemented in exactly the same way.
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.
My apologies for missing that ID_signedbv actually has this documented.
INT_MIN % -1 is, in principle, defined to be zero in ANSI C, C99, C++98, and C++11. Most compilers, however, fail to produce zero, and in some cases generate an exception. C11 explicitly makes this case undefined. This commit adds a check for this particular case, classified as signed overflow.
de08db4 to
53a79b6
Compare
allredj
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 53a79b6).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/96387698