Conversation
Th0rOnDoR
requested review from
kroening,
peterschrammel,
remi-delmas-3000 and
tautschnig
as code owners
September 11, 2026 16:57
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #9163 +/- ##
========================================
Coverage 80.83% 80.83%
========================================
Files 1717 1717
Lines 190069 190077 +8
Branches 73 73
========================================
+ Hits 153647 153655 +8
Misses 36422 36422 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cbmc crashes with an invariant violation in boolbv_mapt::get_literals when an array is first defined as extern with an unknown size and later refined with a defined size The array is first declared with an unknown size (array[nil]), indexed in a function body, and later defined with a concrete size. The C front-end typechecks the function body before the sized definition, so the symbol expressions in that body keep the stale size-less type array[nil] (copied at typecheck time in typecheck_expr_symbol). The symbol table is later refined to array[64], but code bodies are not rewritten — leaving the same object typed both as a size-less and as a sized array. In the solver, the zero-init equality is converted with the concrete type array[64] (4096 bits) while the index expression is converted with array[nil] (treated as unbounded : width 0). Since boolbv_mapt is keyed by identifier only, the second lookup finds the 4096-literal entry and 4096 != 0 trips the invariant. The existing adjust_tentative_array_definitions fix (Fixes diffblue#7608) only handles arrays that are still size-less at end of TU (rewritten to size 1); it does not cover the size-less to concrete refinement. Signed-off-by: Th0rOnDoR <thomas.courrege@thorondor.fr>
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.
cbmc crashes with an invariant violation in boolbv_mapt::get_literals ("number of literals in the literal map shall equal the bitvector width") on programs like:
The array is first declared with an unknown size (array[nil]), indexed in a function body, and later defined with a concrete size. The C front-end typechecks the function body before the sized definition, so the symbol expressions in that body keep the stale size-less type array[nil] (copied at typecheck time in typecheck_expr_symbol). The symbol table is later refined to array[64], but code bodies are not rewritten, leaving the same object typed both as a size-less and as a sized array.
In the solver, the zero-init equality is converted with the concrete type array[64] (4096 bits) while the index expression is converted with array[nil] (treated as unbounded : width 0). Since boolbv_mapt is keyed by identifier only, the second lookup finds the 4096-literal entry and 4096 != 0 trips the invariant.
The existing adjust_tentative_array_definitions fix (Fixes #7608) only handles arrays that are still size-less at end of TU (rewritten to size 1); it does not cover the size-less : concrete refinement.
In typecheck_redefinition_non_type (src/ansi-c/c_typecheck_base.cpp), at the point the array size is refined from unknown to a concrete value, rewrite the symbol expressions referring to that symbol across the symbol table so they carry the concrete array type. This uses unchecked_replace_symbolt, the same mechanism as adjust_tentative_array_definitions, keeping the symbol's type and the types carried on its uses consistent.
Tests:
Added regression test regression/cbmc/Extern_Array_Size_Refinement/ (extern unsized array indexed before its sized definition). It crashes (invariant violation) without the fix and passes with it.
Each commit message has a non-empty body, explaining why the change was made.
Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
My commit message includes data points confirming performance improvements (if claimed).
My PR is restricted to a single feature or bugfix.
White-space or formatting changes outside the feature-related changed lines are in commits of their own.