Fix typing of array expressions within an C ternary ? : operator#9012
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #9012 +/- ##
========================================
Coverage 80.55% 80.55%
========================================
Files 1707 1707
Lines 189047 189051 +4
Branches 73 73
========================================
+ Hits 152292 152296 +4
Misses 36755 36755 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
tautschnig
approved these changes
May 22, 2026
… ID_if Issue diffblue#9008 reported that, for some C inputs, the SMT2 back-end emitted an ill-typed (select <bit-vector> <index>) form. Conforming SMT-LIB 2 solvers (Bitwuzla, cvc5, the bundled cprover smt2_solver) reject such formulas with messages like "select expects array operand"; Z3 accepts them with a warning, which is why the issue had been latent until non-Z3 solvers were used on the mlkem-native proofs. The root cause is a mismatch between use_array_theory and the actual encoding chosen by convert_expr for an array-typed if-then-else: - use_array_theory(if_expr) used to fall through to the generic case return use_datatypes || expr.id() != ID_member; which returns true unconditionally for ID_if (since ID_if != ID_member). - convert_expr's ID_if handler, on the other hand, only produces an SMT-array ITE when at least one branch uses array theory; otherwise it produces a plain bit-vector ITE (the asymmetric case where exactly one branch is bit-vector encoded was already handled by 769f7a2 ("SMT2 back-end: ite-conversion must uphold type consistency"), which inserts an unflatten on the bit-vector branch). When both branches were bit-vector-encoded -- typically because they were member accesses of a struct flattened to a bit-vector -- the conversion thus emitted a bit-vector ITE, but use_array_theory still claimed the corresponding expression had array sort. Callers of use_array_theory (convert_index, convert_with, flatten2bv, the array-typed define-fun path) then wrapped the bit-vector ITE in array-theory operators such as (select ...) or (store ...), producing ill-typed SMT. This commit teaches use_array_theory the matching rule: an array-typed if-then-else uses array theory iff at least one of its branches does. That mirrors convert_expr's behaviour in all four combinations and fixes the symmetric bit-vector case while leaving the previously handled cases untouched. Companion to 769f7a2; together the two commits make the SMT2 back-end produce well-typed SMT for any combination of branch encodings in an array-typed ITE. A regression test, regression/cbmc/issue_9008_smt_array_ite_typing, exercises a conditional pointer dereference into a struct nested in an array. Without this fix the bundled smt2_solver reports "select expects array operand" and CBMC exits with VERIFICATION ERROR; with the fix the assertion is checked normally and reported as FAILURE. Fixes: diffblue#9008 Signed-off-by: Rod Chapman <rodchap@amazon.com> Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
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.
Fixes #9008.
Summary
For some C inputs, the SMT2 back-end emitted ill-typed SMT-LIB 2 of the form
(select <bit-vector> <index>), which conforming solvers (Bitwuzla, cvc5,the bundled
smt2_solver) reject with messages such as "select expectsarray operand"; Z3 silently accepts it with a warning, which is why this
had been latent until non-Z3 solvers were used on the mlkem-native proofs.
The bug was a mismatch between
smt2_convt::use_array_theoryand theencoding actually chosen by
convert_exprfor an array-typed if-then-else:convert_expr'sID_ifhandler emits an SMT-arrayiteonly when atleast one branch uses array theory; otherwise it emits a bit-vector
ite. The asymmetric case (exactly one branch encoded as a bit-vector)was already handled in 769f7a2 by inserting an
unflattenon thebit-vector branch.
use_array_theory(if_expr), however, fell through toreturn use_datatypes || expr.id() != ID_member;, which istrueunconditionally for
ID_if.When both branches were bit-vector-encoded — typically because they were
member accesses of a struct flattened to a bit-vector —
use_array_theorydisagreed with the actual encoding, and callers (
convert_index,convert_with,flatten2bv, the array-typeddefine-funpath) wrappedthe bit-vector ITE in array-theory operators, producing ill-typed SMT.
This PR teaches
use_array_theorythe matching rule: an array-typedif-then-else uses array theory iff at least one of its branches does.
That mirrors
convert_exprin all four branch-encoding combinationsand is a companion to 769f7a2.
Regression test
regression/cbmc/issue_9008_smt_array_ite_typingexercises a conditionalpointer dereference into a struct nested in an array. Run with
--cprover-smt2, the bundledsmt2_solverrejects the malformedformula without this fix (
VERIFICATION ERROR); with the fix theassertion is reported as
FAILUREas expected. The test runs as partof the existing
make -C regression/cbmc test-cprover-smt2step in CI.Checklist