Repository navigation
verify: Keep the state of a loop whose condition is the constant false - #17
Merged
Merged
Conversation
…e instead of havocking it.
…ion, and require no measure of it.
…ied in DESIGN.md.
…h an explicit conversion, not the havoc of a loop that does not run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A loop that never runs still havocked every variable it assigns, so its function was refuted with a counterexample no execution produces.
do { ... } while (0), the usual way to write a statement-like macro, is such a loop:On main this fails an overflow check with
a = -2, andint r = x; while (false) { r = r + 1; } return r;failspost(result == x). Without adecreasesclause either would also have beendecreases.missing.A loop whose condition is a constant false (an integer constant expression, such as
while (false)and the macro'swhile (0)) now keeps every variable it would change, and needs no measure, since it never repeats. Its invariants are still checked on entry. Any other loop is unchanged. Keeping the entry state wherever the condition is false on entry would be exact too, but the extra case split cost the proof ofencode_uleb128inllvm_uleb128.cpp(solver.timeout), so such a loop stays described by its invariant.old_loop_invariant_definedness_fail.cppfailed only through this havoc. Contract arithmetic is mathematical, so itsold(value + 1)cannot overflow; the failures it saw were spurious postcondition counterexamples. Its first two cases now convert explicitly,old((int)(value + 1)), the overflow they meant, and the test checks the obligation kind.Testing:
suite/loop_zero_iterations.cppfails on main, and fails if either change is removed (the Layer 2 check sees the kept values). Verify suite: 398 passed, 1 unsupported, with the repaired test. A verdict differential against main over the 405 Verify sources changes only the two cases above (2959 s on main, 2895 s here).