Repository navigation
verify: Let an unsupported construct cost its function alone - #69
Merged
Merged
Conversation
…the toolchain once.
…eft out, also when it comes first.
…ugh a rejected module.
… module that redeclares a name.
… in the architecture.
…the prelude on its own.
…they apply to Specs.
…hen a User lemma uses sorry.
… again only when what it imports changed.
…moved proof's imports.
…r does not represent.
…the release notes.
… at most 4096 integers.
… verdict and not an abort.
… to report, so no header's is mangled.
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.
Stacked on #68 (LM1b, on #67, #66, #65, #62, and #63), whose commits show here until they merge; merge after #68.
One construct the verifier does not represent stopped the whole file: its error was printed and no function of the file was verified. On the base, for a file with a
switchinpick, a functionincthat is fine, and a calleruserofpick:and nothing else, exit status 1. Now the error is the same and costs
pickalone:Design
Decided for 0.2 (E1): an unsupported construct affects only its function; the function is
Unresolved [reason=construct.unsupported]with the located message, callers relying on its contract are demoted through the existing fixpoint, users of a spec that failed to convert are demoted too, every other function is verified, and the exit status stays non-zero (Q5).codegen_unimplemented), so only what reaches it is affected; Prusti and Creusot report an unsupported feature as an error for its function and verify the others. Frama-C, Dafny, and Verus stop at a front-end error. cpp-verify keeps the error as Clang prints it, as Prusti does, and gives the function its verdict.ConversionError::InContract) or the body. The errors that passes after conversion find about one function (a recursion without a measure, a mutual recursion without a shared measure, a malformed inductive predicate) belong to it too (errorOf; the inductive pass now reports the predicate). So do the two translation-unit errors about functions (a contracted member function, a function template). An error of no function still stops the run.markUnsupported,VFunction::UnsupportedConstruct), what others may rely on:callee.contract, "it uses a construct the verifier does not support"), and the calls of its body are unverified callers of their callees;unsupportedobligation where it is ("a call of lookup, whose contract is not available");constexprhelper, becomes a declaration without its definition, postconditions, reads, domain, or unfolding, which nothing may assume. A function whoseSpecDependencies(bodies, contracts, callees' contracts) reach it is not verified at all:Unresolved [reason=construct.unsupported]("relies on choice, which uses a construct the verifier does not support"). A proof modulo an uninterpreted spec would be sound, but none of its counterexamples could be checked, and this reason names the cause."status":"unresolved","reason":"construct.unsupported"with the range, and every error names its function. A translation unit whose functions are all unsupported still exits 1 (the first version returned success there with "no verifiable functions found";z3_types_fail_closed.cppand two other tests caught it).Assertions build
The first CI run's Linux assertions job failed 32 tests on
GlobalDecl::Init: Use other ctor with dtor decls!: the errors of member functions now name their function by its identity, which mangles it, andfunctionIdentitybuiltGlobalDecl(FD)for every function, a constructor or destructor (the implicit ones of a record) included, which a release build mangles without the check. A constructor or destructor is now mangled as its complete-object variant (Ctor_Complete,Dtor_Complete); the identities of every other function are unchanged. The 32 tests pass on an assertions build.Windows
The Windows smoke test failed. Its program includes
<filesystem>and<vector>, and naming the errors of templates and member functions mangled every one in the translation unit, the headers' included, before asking whether it had contracts to report. Microsoft's mangler cannot mangle a dependent type (cannot mangle this dependent-length yet,cannot mangle this template specialization type yet), so every run under the MSVC target stopped with those errors. Only a template or member function with contracts, the one that is reported, is now named.microsoft_identity.cppverifies a function beside an uncontracted function template with a dependent array length, a class template's member, and a plain member, under--target=x86_64-pc-windows-msvc; on the base it fails with twocannot mangleerrors.Tests
suite/per_function_errors.test, onInputs/per_function_errors.cpp, with Z3, JSON, BMC, and Lean export:pick(a body with aswitch) and its calleruses_pick:callee.contract;lookup(a precondition reading a global array) and its caller: the call isconstruct.unsupported;choice(a spec with aswitch), a function whose postcondition applies it and a lemma about it: bothconstruct.unsupported, "relies on choice";zero_lemma(a proof function with aswitch) and a function that calls it in a ghost block:callee.contract;step(an uncontractedconstexprhelper with aswitch) and its caller:construct.unsupported;inc,twice, anduses_twiceverify as before; no unsupported function gets a verdict of its own;lookupnames it, and the other verdicts are as in text;located_errors.cppnow also checks the records ofpickand ofdown(a recursion without a measure, found after conversion), which carry their verdicts.Mutants, each built and run on
per_function_errors.test,located_errors.cpp,z3_types_fail_closed.cpp,deep_expressions.test, andobject_layout_array_fails_closed.cpp: 10 of 10 killed.per_function_errorsper_function_errorsper_function_errorsper_function_errorsper_function_errorsper_function_errorsper_function_errors,located_errorslocated_errorsz3_types_fail_closed,deep_expressions,object_layout_array_fails_closedper_function_errors,located_errorsDocs
docs_examples.test); what others may rely on; the JSON record.construct.unsupportedfor a function the verifier does not represent and for its users.Open
constexprhelper rejected before its body (an aggregate return, an unsupported parameter type) has no declaration: a user of it endsencoding.failed("missing spec definition"), fail-closed, but without naming the cause.Checked
docs_examples.testchecks the new tooling example.per_function_errors.teston the base: the file stops after its errors, with no verdict.microsoft_identity.cpp,template_contracts.cpp, andlocated_errors.cpppass on an assertions build of this branch, and the first fails on the base.