cprover: state-encoding for uninterpreted functions and member/index lvalues#9069
Open
tautschnig wants to merge 2 commits into
Open
cprover: state-encoding for uninterpreted functions and member/index lvalues#9069tautschnig wants to merge 2 commits into
tautschnig wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates state encoding to better handle uninterpreted (mathematical) function symbols and lvalue member/index chains, and adjusts SMT2 conversion behavior.
Changes:
- Enable datatype support in the SMT2 state-encoding target.
- Avoid state-encoding pure mathematical-function symbols; refine member/index handling to only use address-based evaluation when the base is addressable.
- Avoid splitting struct-tag assignments when RHS is a computed full-struct value (function application / if-then-else).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/cprover/state_encoding_targets.h | Enables SMT2 datatypes in the state-encoding converter. |
| src/cprover/state_encoding_targets.cpp | Changes pointer-related size conversion to fall back when size_of_expr fails. |
| src/cprover/state_encoding.cpp | Adjusts expression evaluation and struct assignment splitting to accommodate uninterpreted functions / computed structs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #9069 +/- ##
===========================================
+ Coverage 80.68% 80.78% +0.09%
===========================================
Files 1714 1714
Lines 189522 189606 +84
Branches 73 73
===========================================
+ Hits 152925 153175 +250
+ Misses 36597 36431 -166 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
78c4acf to
6dcb7fe
Compare
…lvalues Three complementary state-encoding fixes: - Leave mathematical-function (uninterpreted function) symbols unencoded as state variables, so the callee symbol of a function_application survives evaluate_expr_rec. - Route member/index reads whose base is not an addressable lvalue (e.g. a function_application returning a struct) through the operand-recursion path, while addressable bases (symbol, dereference, string_constant) keep using the address-based path. The base of the access chain is found via a small member_index_base() helper using the typed accessors. - Do not field-split an assignment whose RHS is a computed whole-struct value (a function_application or if-then-else, possibly behind typecasts), classified by is_whole_struct_value(), since splitting would re-evaluate the value once per field. In the SMT2 target, struct (tuple) values returned by functions require use_datatypes, which is therefore enabled (the targeted solvers support declare-datatypes). The enter-scope-state element size falls back to a unit size for mathematical pointee types (which have no byte size and are not byte-addressed); any other type without a size is unexpected and now fails loudly rather than silently using an arbitrary size. Regression tests cover the if-then-else whole-struct assignment, the mathematical-type enter-scope size fallback, and the datatype emission. The uninterpreted-function and computed-struct member/index read behaviours are exercised by the Strata front end (they require applied mathematical-function symbols, which the in-tree cprover tool does not synthesise from C). Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Reading a field (or element) of an object that was updated with a whole struct/array value was unsound in the state simplifier: evaluate of a field-address against an update of the containing object was treated as non-aliasing, so the whole-object update was dropped and the field read the stale prior state. This produced spurious counterexamples, e.g. for struct S t; t = c ? a : b; assert(t.x == (c ? a.x : b.x)); Add three simplification rules to simplify_state_expr: - evaluate(field_address(A, f), ς[A := V]) --> member(V, f), and likewise for element_address (the missing whole-object/sub-component overlap case); - member(evaluate(ς, A), f) --> evaluate(ς, field_address(A, f)), and the analogous index rule, bridging the datatype (whole-value) view of a struct and the field-address (scalar) view so both agree; - distribution of member/index over if, so the bridge applies to each arm of a conditional whole-struct value. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
6dcb7fe to
1cab0d4
Compare
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.
Leave mathematical-function (uninterpreted function) symbols unencoded as state variables, and follow member/index chains to the addressable base expression when state-encoding lvalues.