Repository navigation
verify: Contain a slice argument through the objects it may address - #51
Merged
Merged
Conversation
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 function that requires
valid(p, n)accepted an argument only when the argument was written as one of the caller's parameters plus an offset. Any other argument failed with a counterexample, even when the program was correct. That is a wrongFailedverdict, in 0.1.1 and onmain:first(a + 1, 3)verified, butfirst(q, 3)withq = a + 1did not. The same happened for:c ? a + 1 : b);q = q + 1with an invariantq == a + i);post(result == a + 1));q = a + 4; count(q, 0)).Cause
At a call,
sliceContainment(Passivize.cpp) proves an extent argument's containment syntactically. The argument's base must be a caller parameter with an extent; otherwise the obligation is the literalfalse, of kindbounds. The callee's validity preconditionValidPtr(actual)was likewise discharged only by rewriting the actual to that parameter base. A literalfalseis refuted by any model, so the result was a "certified" counterexample about a correct program.Fix
Containment is now semantic, as access checks already are:
[actual, actual + n * S]lie in one of the caller's objects. These are the entry objects its origins name (the objects it may address), or any of the caller's objects when its origins are unknown, as for a call result (Passivizer::objectContainment). Validity is a property of storage, so any object that contains the elements establishes it; origins only narrow the disjunction. This is the same rule a single-object argument already follows (abstractValidity).ValidPtr(actual)is discharged by the same membership.Where the syntactic rule applies, the call produces exactly the query it did before. Only calls whose containment was the literal
falsechange. Both changes replace a check that could never succeed by one that holds exactly when the argument's elements lie in the caller's storage, so a false claim cannot verify. The test's false twins check this: three elements froma + 2, a choice whoseaside is too short, a result whose contract does not place it, and a walk that stops too early.This also prepares B3a-2. A pointer to an array member passed to a buffer function needs this containment, and B3a-2 adds the member's bounds to it.
Tests
suite/slice_argument_objects.cppcontains:c = truefor the choice, and a trusted result one element beforea, whose slice would end insidea.On
mainevery function in the file except the callees fails.Docs
Checked
On
mainat 5165654:Verify lit suite: 427 passed and 1 unsupported, on both the release build and an assertions build. This includes the docs tests.
VerifyTests: 60 passed, 1 skipped.
On
main:slice_argument_objects.cppfails.Verdict differential against
main: 435 test sources. Only the new test differs, and no file's time changed (3530 s → 3501 s in total). An earlier version added the object containment to every extent call, and in that versiondecode_uleb128_length_11timed out. Using it only where the syntactic rule fails keeps every other query as it was.Mutation: 8 mutants, all killed by the test. They:
The start-bound mutant at first survived; the trusted
beforecase now kills it.Docs:
check-doc-examples.pypasses on every page this changes (62 examples, 10 against the verdicts their pages show).Merges: this merges cleanly with each open PR, verify: Follow the body of a choose in a spec's reads and postcondition checks #43, verify: Make chooses with one condition one choice, kept across writes elsewhere #44, verify: Send crash reports to cpp-verify's issue tracker #46, and verify: Bound what a run builds and what its solvers allocate #48 to verify: Reach the fields and array elements of a record through a pointer #50.