Skip to content

Add automated overflow/underflow checks for bitvector arithmetic#592

Merged
tautschnig merged 30 commits intomainfrom
tautschnig/overflow-checks
Apr 15, 2026
Merged

Add automated overflow/underflow checks for bitvector arithmetic#592
tautschnig merged 30 commits intomainfrom
tautschnig/overflow-checks

Conversation

@tautschnig
Copy link
Copy Markdown
Contributor

@tautschnig tautschnig commented Mar 17, 2026

Motivation

Arithmetic overflow is a major source of bugs in systems code. Signed integer overflow is undefined behavior in C/C++, unsigned overflow silently wraps, and floating-point overflow silently produces infinity. Unlike division-by-zero (added in #510), these errors are easy to miss in code review and hard to trigger in testing.

This PR extends Strata's automated verification to catch arithmetic overflow at every use site — the same way #510 catches every division by zero — so that front-end languages like Laurel (and future C/Java front-ends) get overflow checking for free, without any source-level instrumentation.

Approach

Following the pattern established by #510 for division-by-zero:

  1. Safe operator variants (e.g., Bv32.SafeAdd) carry built-in preconditions asserting that overflow does not occur.
  2. The existing PrecondElim transform automatically generates verification conditions at each use site.
  3. Front-end translators emit safe variants instead of unchecked ones — no language-level instrumentation required.

This keeps the architecture uniform: the same mechanism handles division-by-zero, signed overflow, unsigned overflow, and signed division overflow (INT_MIN / -1).

What's covered

Signed bitvector overflow (all sizes: bv1, bv2, bv8, bv16, bv32, bv64):

  • SafeAdd/SafeSub/SafeMul/SafeNeg with preconditions using SMT-LIB's bvsaddo/bvssubo/bvsmulo/bvnego

Signed division overflow (INT_MIN / -1):

  • SafeSDiv/SafeSMod with dual preconditions: divisor ≠ 0 AND ¬(dividend = INT_MIN ∧ divisor = −1)

Unsigned bitvector overflow (configurable via unsignedOverflowCheck option):

  • SafeUAdd/SafeUSub/SafeUMul/SafeUNeg with unsigned overflow predicates

GOTO backend:

  • Overflow predicates translate to CBMC's native overflow-+, overflow--, overflow-*, overflow-unary- expressions
  • Safe operators translate to the same GOTO operations as their unchecked counterparts

Key design decisions

  • Safe variants are opt-in at the Core levelBv32.Add (wrapping) and Bv32.SafeAdd (checked) coexist. Front-end translators choose which to emit.
  • Unsigned overflow is off by default — wrapping is the intended semantics in most languages. Enable with unsignedOverflowCheck := true.
  • Signed overflow is always checked when using safe variants — this matches C/C++ undefined behavior semantics.
  • The GOTO backend uses CBMC's native overflow expressions rather than the SMT encoding, so CBMC's solver infrastructure handles them natively.

Description of changes:

New arithmeticOverflow property type alongside the existing divisionByZero, with SARIF classification, display labels, and check mode handling. Overflow predicates and safe operators for all BV sizes generated via Lean4 macros. SMT encoding for signed overflow uses SMT-LIB builtins; unsigned uses custom encodings. Comprehensive unit tests verify factory presence, WF obligation generation, and GOTO translation.

Co-authored-by: Kiro kiro-agent@users.noreply.github.com

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

tautschnig and others added 8 commits March 17, 2026 10:10
Add PropertyType.arithmeticOverflow alongside the existing divisionByZero
property type. This is the foundation for bitvector and floating-point
overflow/underflow checks.

Changes:
- EvalContext.lean: new PropertyType.arithmeticOverflow variant
- MetaData.lean: new MetaData.arithmeticOverflow constant
- StatementEval.lean: recognize "arithmeticOverflow" in metadata
- Verifier.lean: display labels/emoji, check mode handling
- SarifOutput.lean: SARIF classification "arithmetic-overflow"
- PrecondElim.lean: classify BvN.Safe* operators as overflow checks

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Add safe BV operator variants (SafeAdd, SafeSub, SafeMul, SafeNeg) with
built-in overflow preconditions for all BV sizes (1, 2, 8, 16, 32, 64).
Each safe operator carries a precondition asserting that the corresponding
signed overflow predicate is false.

New overflow predicate functions (SAddOverflow, SSubOverflow, SMulOverflow,
SNegOverflow) are added as factory functions that map to SMT-LIB's bvsaddo,
bvssubo, bvsmulo, and bvnego operations.

The PrecondElim transform automatically generates verification conditions
at each use site of a safe operator, classified as 'arithmeticOverflow'
property type.

Changes:
- IntBoolFactory.lean: add optional preconditions parameter to unaryOp
- Factory.lean: new BVEvalKind variants (overflowBinary/overflowUnary),
  BVSafeOpSpecs, ExpandBVSafeOpFuncDefs/Names/Exprs macros
- SMTEncoder.lean: map safe ops to normal SMT ops, overflow predicates
  to bvsaddo/bvssubo/bvsmulo/bvnego
- ASTtoCST.lean: handle safe ops and overflow predicates in CST printing
- New OverflowCheckTest.lean: unit tests verifying factory presence and
  WF obligation generation
- Updated ProgramTypeTests.lean, ProcedureEvalTests.lean: new factory
  function listings

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Add SafeSDiv and SafeSMod operators that check both division-by-zero
(y ≠ 0) and signed division overflow (x ≠ INT_MIN ∨ y ≠ -1) for all
BV sizes. These use the new SDivOverflow predicate which leverages
Lean4's BitVec.sdivOverflow from the standard library.

Each SafeSDiv/SafeSMod carries two preconditions:
1. ¬(y == 0) — division by zero (classified as divisionByZero)
2. ¬SDivOverflow(x, y) — INT_MIN / -1 overflow (classified as arithmeticOverflow)

Changes:
- Factory.lean: SDivOverflow predicate in BVOpSpecs, SafeSDiv/SafeSMod
  via ExpandBVSafeDivOpFuncDefs macro with dual preconditions
- SMTEncoder.lean: SDivOverflow encoded as (x == INT_MIN) ∧ (y == -1),
  SafeSDiv/SafeSMod map to bvsdiv/bvsrem
- ASTtoCST.lean: SafeSDiv/SafeSMod CST printing
- Updated test expected outputs

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Add unsigned overflow predicates (UAddOverflow, USubOverflow, UMulOverflow,
UNegOverflow) and safe unsigned operators (SafeUAdd, SafeUSub, SafeUMul,
SafeUNeg) for all BV sizes.

Unsigned overflow is controlled by the new unsignedOverflowCheck option
in VerifyOptions (default: false). Front-end translators use the safe
unsigned variants when this option is enabled.

SMT encoding for unsigned overflow predicates:
- UAddOverflow: bvult(bvadd(x, y), x) — wrapping add < operand
- USubOverflow: bvult(x, y) — unsigned subtraction underflow
- UMulOverflow: bvugt(zero_extend(N, x) * zero_extend(N, y), zero_extend(N, MAX))
- UNegOverflow: x != 0

Note: ProgramTypeTests and ProcedureEvalTests expected output needs
updating for the new factory functions (the OverflowCheckTest validates
the core functionality).

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Teach the GOTO backend to translate overflow predicate expressions to
CBMC's native overflow expression types:
- SAddOverflow/UAddOverflow → overflow-+ (PlusOverflow)
- SSubOverflow/USubOverflow → overflow-- (MinusOverflow)
- SMulOverflow/UMulOverflow → overflow-* (MultOverflow)
- SNegOverflow/UNegOverflow → overflow-unary- (UnaryMinusOverflow)

Safe operators (SafeAdd, SafeSub, etc.) translate to the same GOTO
operations as their unsafe counterparts (Plus, Minus, etc.), since
the overflow checks are handled by PrecondElim-generated assertions.

Changes:
- Expr.lean: add MinusOverflow, MultOverflow (Binary), UnaryMinusOverflow
  (Unary) with format strings and helper constructors
- LambdaToCProverGOTO.lean: map overflow predicates and safe ops in
  fnToGotoID; add signed ops to isSignedBvOp
- Tests: verify overflow predicate → GOTO expression mapping

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Add IEEE 754 double-precision floating-point support to the SMT layer
and Core language, with safe arithmetic operators for overflow detection.

SMT layer:
- TermPrimType.float64: maps to (_ FloatingPoint 11 53) in SMT-LIB
- TermPrim.rne: RoundNearestTiesToEven rounding mode constant
- Op.FP: fp.add, fp.sub, fp.mul, fp.div, fp.neg, fp.isInfinite, fp.isNaN,
  fp.isZero operations
- DDM Translate: float64 sort and rne constant encoding

Core Factory:
- Float64.Add/Sub/Mul/Div/Neg: basic arithmetic (unevaluated)
- Float64.IsInfinite/IsNaN: predicates
- Float64.SafeAdd/SafeSub/SafeMul/SafeDiv: overflow-checked variants
- SMT encoding: FP ops use RNE rounding mode

Laurel integration:
- TFloat64 now maps to LMonoTy.float64 (was "Float64IsNotSupportedYet")
- Arithmetic on Float64 uses safe variants (SafeAdd/Sub/Mul/Div)
- PrecondElim classifies Float64.Safe* as arithmeticOverflow

Note: Float64 safe ops are currently unevaluated (no preconditions via
binaryOp). Full overflow checking (result becomes ±infinity from finite
inputs) requires a dedicated transform that inserts assertions using
Float64.IsInfinite, similar to CBMC's float_overflow_check approach.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…encoding

Address all remaining work items:

1. Test file updates:
   - ProgramTypeTests.lean: replaced docstring with actual output including
     all new factory functions (Float64, unsigned overflow, safe ops)
   - ProcedureEvalTests.lean: same
   - TypeDecl.lean: added float64 to known types list

2. Float64 overflow predicates:
   - Float64.AddOverflow/SubOverflow/MulOverflow/DivOverflow: predicates
     that return true when finite inputs produce infinite result
   - SMT encoding: ¬isInfinite(x) ∧ ¬isInfinite(y) ∧ isInfinite(fp.op(RNE, x, y))
   - Following CBMC's float_overflow_check approach

3. Bug fixes:
   - UAddOverflow SMT encoding: use operand type (not return type) for bvadd
   - SMT Denote: add float64 case (returns none)
   - SMT Translate: add float64 case (throws unsupported)
   - Remove Float64IsNotSupportedYet datatype from HeapParameterizationConstants
   - Add float64 to KnownLTys so Core type checker recognizes it

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Replace #check with example := for silent compilation checks.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig requested a review from a team March 17, 2026 14:02
Copilot AI review requested due to automatic review settings March 17, 2026 14:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Strata’s “safe operator + PrecondElim” verification pipeline (previously used for division-by-zero) to also generate verification conditions for arithmetic overflow/underflow across bitvector operations and (newly supported) Float64, with a new arithmeticOverflow property type surfaced through reporting/SARIF and supported in the CBMC GOTO backend.

Changes:

  • Introduces new Core bitvector overflow predicate functions and corresponding Safe* operators intended to carry overflow preconditions (plus special handling for signed div overflow).
  • Adds an SMT-layer float64 sort and Float64 operators/predicates, and updates Laurel’s TFloat64 translation to use real Float64 operators.
  • Adds reporting/plumbing for the new arithmeticOverflow property type (labels/emojis/SARIF classification) and adds/updates tests for factory presence and backend translation.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
StrataTest/Languages/Core/Tests/ProgramTypeTests.lean Updates expected environment dump to include new Float64/BV overflow/safe functions.
StrataTest/Languages/Core/Tests/ProcedureEvalTests.lean Updates expected prelude with new Float64/BV overflow/safe functions.
StrataTest/Languages/Core/Tests/OverflowCheckTest.lean Adds unit tests for presence of safe ops/predicates and WF obligation generation.
StrataTest/Languages/Core/Examples/TypeDecl.lean Updates expected reserved-type list to include float64.
StrataTest/Backends/CBMC/GOTO/LambdaToCProverGOTO.lean Adds tests for mapping overflow predicates and safe ops to CBMC identifiers.
Strata/Transform/PrecondElim.lean Classifies safe BV/Float64 preconditions as arithmeticOverflow for SARIF/reporting.
Strata/Languages/Laurel/LaurelToCoreTranslator.lean Translates Laurel Float64 types/ops to Core Float64 (and uses Float64 safe ops for arithmetic).
Strata/Languages/Laurel/HeapParameterizationConstants.lean Removes the old placeholder Float64IsNotSupportedYet datatype.
Strata/Languages/Core/Verifier.lean Extends minimal/full label+emoji logic to include arithmeticOverflow.
Strata/Languages/Core/StatementEval.lean Maps MetaData.propertyType strings to the new .arithmeticOverflow PropertyType.
Strata/Languages/Core/SarifOutput.lean Adds SARIF classification string for arithmeticOverflow and updates unreachable handling comment.
Strata/Languages/Core/SMTEncoder.lean Adds SMT encoding for float64 sort/ops, float overflow predicates, signed overflow builtins, and unsigned overflow encodings.
Strata/Languages/Core/Options.lean Adds unsignedOverflowCheck option field (default false).
Strata/Languages/Core/Factory.lean Adds float64 to known types; generates BV overflow predicates and BV safe ops; adds Float64 functions to the factory.
Strata/Languages/Core/DDMTransform/ASTtoCST.lean Extends CST translation mappings for safe BV ops (and attempts overflow predicate handling).
Strata/DL/Util/BitVec.lean Adds BitVec.unegOverflow.
Strata/DL/SMT/Translate.lean Rejects float64 sort in Lean-denotation translation.
Strata/DL/SMT/TermType.lean Adds float64 to SMT term primitive types.
Strata/DL/SMT/Term.lean Adds rounding-mode primitive rne and its typing.
Strata/DL/SMT/Op.lean Adds SMT-LIB floating-point ops (fp.add/sub/mul/div, etc.) and abbrev generation.
Strata/DL/SMT/Denote.lean Marks float64 as having no Lean denotation.
Strata/DL/SMT/DDMTransform/Translate.lean Emits SMT-LIB (_ FloatingPoint 11 53) for float64 and emits RNE constant.
Strata/DL/Lambda/LTy.lean Adds LMonoTy.float64.
Strata/DL/Lambda/IntBoolFactory.lean Extends unaryOp helper to accept preconditions (for safe operator construction).
Strata/DL/Imperative/MetaData.lean Adds MetaData.arithmeticOverflow classification string constant.
Strata/DL/Imperative/EvalContext.lean Adds PropertyType.arithmeticOverflow and integrates it into formatting/unreachable semantics.
Strata/Backends/CBMC/GOTO/LambdaToCProverGOTO.lean Maps safe ops and overflow predicates to CBMC GOTO overflow IDs and marks them as signed BV ops where appropriate.
Strata/Backends/CBMC/GOTO/Expr.lean Adds CBMC expression identifiers for minus/mult/unary-minus overflow and helper constructors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Strata/Languages/Core/DDMTransform/ASTtoCST.lean Outdated
Comment thread Strata/Languages/Core/DDMTransform/ASTtoCST.lean Outdated
Comment thread Strata/Transform/PrecondElim.lean
Comment thread Strata/Languages/Core/Options.lean Outdated
Comment thread Strata/Languages/Core/Factory.lean Outdated
…T handling

Address all 5 Copilot review comments:

1. Float64 safe ops now carry overflow preconditions (Comment 5):
   Float64.SafeAdd/Sub/Mul/Div each require ¬Float64.*Overflow(x, y).
   PrecondElim now generates overflow VCs at each Float64 use site.

2. SafeSDiv/SafeSMod div-by-zero classification (Comment 3):
   classifyPrecondition now takes a per-function precondition index.
   For SafeSDiv/SafeSMod, precondition 0 (y≠0) is classified as
   divisionByZero, precondition 1 (INT_MIN/-1) as arithmeticOverflow.

3. ASTtoCST overflow predicate handling (Comments 1 & 2):
   - SNegOverflow/UNegOverflow: changed from neg_expr to Bool.Not
   - Binary overflow predicates (SAddOverflow etc.): added to
     bvBinaryOpMap with boolean approximation for CST printing
   - These only appear in generated assertions, not user code

4. unsignedOverflowCheck documentation (Comment 4):
   Added doc comment explaining the option is forward-looking
   infrastructure, to be wired when front-end languages gain BV types.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Comment thread Strata/Languages/Laurel/LaurelToCoreTranslator.lean Outdated
@tautschnig tautschnig self-assigned this Mar 19, 2026
tautschnig and others added 2 commits March 19, 2026 10:36
Replace the unused unsignedOverflowCheck bool with a structured
OverflowChecks configuration covering signed BV, unsigned BV, and
float64 overflow checks. Defaults match C/IEEE 754 semantics:
signed BV checked (UB in C), unsigned BV unchecked (wraps), float64
unchecked (overflows to ±∞ per IEEE 754).

- Add OverflowChecks structure to Core.Options
- Wire --overflow-checks CLI flag to StrataVerify
- Thread config through LaurelTranslateOptions and TranslateState
- Laurel translator now consults overflowChecks.float64 to choose
  between safe and non-safe float ops (non-safe by default)

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…hecks

# Conflicts:
#	Strata/Languages/Core/Options.lean
#	Strata/Languages/Laurel/HeapParameterizationConstants.lean
#	Strata/Languages/Laurel/LaurelToCoreTranslator.lean
#	StrataVerify.lean
@tautschnig tautschnig removed their assignment Mar 19, 2026
@tautschnig tautschnig enabled auto-merge March 19, 2026 11:34
@shigoel
Copy link
Copy Markdown
Contributor

shigoel commented Mar 21, 2026

I haven't looked at this PR deeply, but I'd recommend removing FP support in Strata's SMT dialect from this PR and keeping it focused only on integers for now. Let's go back to the design board before we use SMTLib's FP theory.

@tautschnig tautschnig self-assigned this Mar 25, 2026
tautschnig and others added 2 commits March 27, 2026 23:42
…hecks

Resolve conflicts:
- Options.lean: keep both overflowChecks and outputSarif fields
- LaurelToCoreTranslator.lean: keep Float64 support, adopt throwExprDiagnostic
  pattern, keep both overflowChecks and coreProgramHasSuperfluousErrors in
  TranslateState
- TypeDecl.lean: include both float64 and Sequence in known types list
- StrataVerify.lean: accept deletion (migrated to strata verify)
- StrataMain.lean: add --overflow-checks flag to verify command

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…cks)

Per reviewer feedback, remove floating-point support from this PR to
keep it focused on integer overflow checks. FP support in the SMT
dialect needs further design discussion before using SMT-LIB's FP theory.

Removed:
- SMT dialect: float64 primitive type, Op.FP operations, rne rounding mode
- Lambda types: LMonoTy.float64
- Core Factory: all Float64 functions (Add/Sub/Mul/Div/Neg, predicates,
  safe ops, overflow predicates)
- Core SMT Encoder: Float64 sort mapping and FP operation encoding
- Laurel translator: TFloat64 type translation and Float64 operator selection
- PrecondElim: Float64.Safe* classification
- MetaVerifier: Op.FP ToExpr instance

Retained:
- OverflowChecks.float64 config field (harmless, ready for future use)
- All integer overflow infrastructure (signed/unsigned BV, division overflow)
- arithmeticOverflow property type and SARIF classification
- GOTO backend overflow expression support

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig
Copy link
Copy Markdown
Contributor Author

I haven't looked at this PR deeply, but I'd recommend removing FP support in Strata's SMT dialect from this PR and keeping it focused only on integers for now. Let's go back to the design board before we use SMTLib's FP theory.

I have now removed the floating-point aspects from this PR.

@tautschnig tautschnig assigned shigoel and unassigned tautschnig Mar 28, 2026
@tautschnig
Copy link
Copy Markdown
Contributor Author

@keyboardDrummer-bot Please resolve git conflicts.

Conflicts resolved:
- Strata/Languages/Laurel/LaurelToCoreTranslator.lean: Took main's
  refactored version (pipeline code moved to LaurelCompilationPipeline.lean)
  and re-applied the PR's overflowChecks additions to TranslateState and
  LaurelTranslateOptions.
- Strata/Languages/Laurel/LaurelCompilationPipeline.lean: Added
  overflowChecks := options.overflowChecks to initState, matching the
  PR's intent now that the pipeline lives in this new file.
- 4 test expected files: Took main's updated expected outputs.
@keyboardDrummer-bot
Copy link
Copy Markdown
Collaborator

I've resolved the git conflicts by merging main into this branch. Here's what I did:

Conflicts resolved (5 files):

  1. Strata/Languages/Laurel/LaurelToCoreTranslator.lean — Main's refactoring (Refactor Laurel compilation pipeline #858) moved the compilation pipeline out of this file into the new LaurelCompilationPipeline.lean. I took main's version (the streamlined ordered.decls.flatMapM approach) and re-applied this PR's overflowChecks additions to both TranslateState and LaurelTranslateOptions.

  2. Strata/Languages/Laurel/LaurelCompilationPipeline.lean (new file from main) — Added overflowChecks := options.overflowChecks to the initState construction, which is where the old translateWithLaurel pipeline now lives.

  3. 4 test expected files (test_class_methods, test_class_mixed_init, test_class_with_methods, test_deep_inline) — Took main's updated expected outputs, which reflect the refactored pipeline behavior.

Verification: Both LaurelToCoreTranslator and LaurelCompilationPipeline build successfully with lake build.

The previous merge (8d208f9) took main's expected outputs for 4 Python
test files, but those didn't account for this PR's PrecondElim.lean
change that strips propertySummary metadata from generated precondition
checks. Regenerated the expected files to match actual output.

Affected files:
- test_class_methods.expected
- test_class_mixed_init.expected
- test_class_with_methods.expected
- test_deep_inline.expected
@keyboardDrummer-bot
Copy link
Copy Markdown
Collaborator

Fixed the CI failure in Build and test Lean (stable) (e57677d).

Root cause: The previous merge conflict resolution (8d208f9) took main's versions of 4 Python expected test output files, but those didn't account for this PR's PrecondElim.lean change that strips propertySummary metadata from generated precondition checks. This caused the run_py_analyze.sh golden-file test step to fail because the expected output labels no longer matched the actual output.

Specifically, auto-generated precondition checks now produce an additional line with a technical label like assert_main_assert(503)_17_calls_Any_to_bool_0 alongside the user-facing message. The merge took main's expected files which only had the user-facing messages.

Fix: Regenerated the 4 affected expected files using run_py_analyze.sh --update:

  • test_class_methods.expected
  • test_class_mixed_init.expected
  • test_class_with_methods.expected
  • test_deep_inline.expected

Verified locally:

  • lake build
  • lake test
  • run_py_analyze.sh ✅ (all golden-file tests pass)
  • run_py_analyze_sarif.py --laurel
  • run_examples.sh
  • testStrataCommand.sh

tautschnig and others added 2 commits April 15, 2026 08:45
Replace verbose match arms that enumerate assert/divisionByZero/
arithmeticOverflow separately with property.passWhenUnreachable checks.
The key insight: all assert-like properties (assert, divisionByZero,
arithmeticOverflow) behave identically, while cover behaves differently.

Affected functions: label, emoji, verifySingleEnv check selection.
This makes the code resilient to adding new assert-like property types.

Addresses shigoel's feedback on PR #592.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Safe BV operators (SafeAdd, SafeSub, SafeMul, SafeNeg, SafeSDiv,
SafeSMod and their unsigned variants) previously mapped to the same
CST constructors as their unsafe counterparts, losing the safe
annotation through AST/CST roundtrip.

Add new grammar productions:
  safe+, safe-, safe*, safe_neg, safesdiv, safesmod

Update ASTtoCST to emit the new constructors for safe operators.
Update Translate to map them back to the safe Factory operators.

Signed and unsigned variants share the same CST syntax (the type
system distinguishes them); CST→AST maps to the signed variant.

Includes SafeBvOps.core.st example and roundtrip test via run_examples.sh.

Addresses shigoel's feedback on PR #592 about safe operators being
lost through AST/CST roundtrip.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Comment thread Strata/Backends/CBMC/GOTO/LambdaToCProverGOTO.lean
joscoh
joscoh previously approved these changes Apr 15, 2026
tautschnig and others added 2 commits April 15, 2026 16:29
… call

SDivOverflow(x, y) was mapped to .functionApplication which CBMC cannot
solve. Now expanded inline to (x == INT_MIN) && (y == -1), matching the
SMT backend's sdivOverflowEnc.

Addresses shigoel's feedback on PR #592.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit ae51719 Apr 15, 2026
17 checks passed
@tautschnig tautschnig deleted the tautschnig/overflow-checks branch April 15, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants