Skip to content

Emit explicit contract:: symbols for functions with contracts#4612

Open
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:explicit-contract
Open

Emit explicit contract:: symbols for functions with contracts#4612
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:explicit-contract

Conversation

@tautschnig

Copy link
Copy Markdown
Member

CBMC's DFCC contract instrumentation (--enforce-contract / --replace-call-with-contract) expects a dedicated contract::<fn> symbol to exist for any function carrying a contract. For C inputs this symbol is created by the ANSI-C typechecker, which also moves the contract clauses (e.g. c_spec_assigns) onto it.

Kani builds goto-programs directly and never runs that typechecker, so the symbol was absent. CBMC used to paper over this by deriving an empty contract symbol from the function on the fly, but that fallback was removed for soundness in diffblue/cbmc#8739, turning the missing symbol into a hard error and breaking every #[kani::proof_for_contract] harness.

Synthesize the companion contract::<name> symbol during symbol-table serialization. It shares the function's contract-bearing type, has no body, and is marked as a property, reconstructing exactly the symbol CBMC's typechecker (and its old fallback) produced.

This is a necessary (though not necessarily sufficient) change to enable upgrading to newer CBMC versions.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

CBMC's DFCC contract instrumentation (`--enforce-contract` /
`--replace-call-with-contract`) expects a dedicated `contract::<fn>`
symbol to exist for any function carrying a contract. For C inputs this
symbol is created by the ANSI-C typechecker, which also moves the
contract clauses (e.g. `c_spec_assigns`) onto it.

Kani builds goto-programs directly and never runs that typechecker, so
the symbol was absent. CBMC used to paper over this by deriving an empty
contract symbol from the function on the fly, but that fallback was
removed for soundness in diffblue/cbmc#8739, turning the missing symbol
into a hard error and breaking every `#[kani::proof_for_contract]`
harness.

Synthesize the companion `contract::<name>` symbol during symbol-table
serialization. It shares the function's contract-bearing type, has no
body, and is marked as a property, reconstructing exactly the symbol
CBMC's typechecker (and its old fallback) produced.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 23, 2026 19:04
@tautschnig tautschnig requested a review from a team as a code owner June 23, 2026 19:04
@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates Kani’s CBMC symbol-table serialization to synthesize the dedicated contract::<fn> symbols required by CBMC’s DFCC contract instrumentation, restoring compatibility with newer CBMC versions where the previous fallback behavior was removed.

Changes:

  • Add a helper to derive a contract::<name> symbol for any function symbol carrying a contract.
  • Emit the companion contract::<name> symbol during goto_program::SymbolTable -> irep::SymbolTable serialization.

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

Comment on lines +720 to +727
fn to_contract_irep(&self, mm: &MachineModel) -> super::Symbol {
let mut contract_symbol = self.to_irep(mm);
contract_symbol.name = format!("contract::{}", self.name).into();
contract_symbol.is_property = true;
// The contract symbol is a pure specification and carries no body.
contract_symbol.value = Irep::nil();
contract_symbol
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants