Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loop Contracts Annotation for While-Loop #3151

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0e49d50
Loop Contracts Annotation for While-Loop
qinheping Apr 19, 2024
a5cc42c
Bump dependencies and Kani's version to 0.50.0 (#3148)
celinval Apr 17, 2024
537eefc
Upgrade toolchain to 2024-04-18 and improve toolchain workflow (#3149)
celinval Apr 18, 2024
4806dac
Automatic toolchain upgrade to nightly-2024-04-19 (#3150)
github-actions[bot] Apr 19, 2024
55e5f0d
Stabilize cover statement and update contracts RFC (#3091)
celinval Apr 19, 2024
0e6c192
Automatic toolchain upgrade to nightly-2024-04-20 (#3154)
github-actions[bot] Apr 22, 2024
dd6e60f
Bump tests/perf/s2n-quic from `2d5e891` to `5f88e54` (#3140)
dependabot[bot] Apr 22, 2024
a542ede
Automatic cargo update to 2024-04-22 (#3157)
github-actions[bot] Apr 22, 2024
3cf110c
Automatic toolchain upgrade to nightly-2024-04-21 (#3158)
github-actions[bot] Apr 22, 2024
4be4214
Bump tests/perf/s2n-quic from `5f88e54` to `9730578` (#3159)
dependabot[bot] Apr 22, 2024
e5b0a2a
Fix cargo audit error (#3160)
jaisnan Apr 22, 2024
b244770
Fix cbmc-update CI job (#3156)
tautschnig Apr 23, 2024
ec29ffd
Automatic cargo update to 2024-04-29 (#3165)
github-actions[bot] Apr 29, 2024
1371195
Bump tests/perf/s2n-quic from `9730578` to `1436af7` (#3166)
dependabot[bot] Apr 29, 2024
5d64679
Do not assume that ZST-typed symbols refer to unique objects (#3134)
tautschnig Apr 30, 2024
7bc0cb8
Fix copyright check for `expected` tests (#3170)
adpaco-aws May 3, 2024
df2c1fb
Remove kani::Arbitrary from the modifies contract instrumentation (#3…
feliperodri May 3, 2024
5edab5d
Annotate loop contracts as statement expression
qinheping May 9, 2024
c8ecefe
Automatic cargo update to 2024-05-06 (#3172)
github-actions[bot] May 6, 2024
bda1f3c
Bump tests/perf/s2n-quic from `1436af7` to `6dd41e0` (#3174)
dependabot[bot] May 6, 2024
eaf5b42
Avoid unnecessary uses of Location::none() (#3173)
tautschnig May 7, 2024
cf5a8f9
Update Rust dependencies (#3175)
karkhaz May 7, 2024
584a3de
Bump Kani version to 0.51.0 (#3176)
karkhaz May 7, 2024
195c453
Merge branch 'main' into features/loop-contracts-annotation
qinheping May 9, 2024
52878c5
Remove leftover code
qinheping May 9, 2024
6547dcd
Remove unused import
qinheping May 9, 2024
319a8b9
Fix format
qinheping May 9, 2024
2569af0
Loop invariants should be operands of named subs
qinheping May 9, 2024
36c7628
Merge branch 'main' into features/loop-contracts-annotation
qinheping Aug 6, 2024
159e6ad
Allow cloned reachability checks
qinheping Aug 6, 2024
fbd17d6
Fix format
qinheping Aug 6, 2024
1a81de2
Fix format
qinheping Aug 7, 2024
3596dbe
Apply Adrian's comments
qinheping Aug 13, 2024
5210107
Use with_loop_contracts
qinheping Aug 13, 2024
54168fd
Fix tests
qinheping Aug 13, 2024
def6b97
Merge branch 'main' into features/loop-contracts-annotation
qinheping Sep 3, 2024
64b66d3
Fix format
qinheping Sep 3, 2024
0b05968
Refactor the loop contracts with closures
qinheping Sep 11, 2024
3624655
Add missing copyright
qinheping Sep 11, 2024
3a481a0
Merge branch 'main' into features/loop-contracts-annotation
qinheping Sep 11, 2024
68554df
Use proc_macro_error2
qinheping Sep 11, 2024
75a82d5
Provide locals to ty()
qinheping Sep 11, 2024
20b8de0
Do loop contracts transformation only for harnesses
qinheping Sep 11, 2024
c82684e
Merge branch 'main' into features/loop-contracts-annotation
qinheping Sep 20, 2024
90c1c5c
Move loop-contracts-hook and add more documentation
qinheping Sep 20, 2024
608baeb
Fix format
qinheping Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions cprover_bindings/src/goto_program/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ pub enum StmtBody {
arguments: Vec<Expr>,
},
/// `goto dest;`
Goto(InternedString),
Goto {
dest: InternedString,
// The loop invariants annotated to the goto, which can be
// applied as loop contracts in CBMC if it is a backward goto.
loop_invariants: Option<Expr>,
qinheping marked this conversation as resolved.
Show resolved Hide resolved
},
/// `if (i) { t } else { e }`
Ifthenelse {
i: Expr,
Expand Down Expand Up @@ -179,7 +184,7 @@ impl Stmt {
stmt!(Assign { lhs, rhs }, loc)
}

/// `assert(cond, property_class, commment);`
/// `assert(cond, property_class, comment);`
pub fn assert(cond: Expr, property_name: &str, message: &str, loc: Location) -> Self {
assert!(cond.typ().is_bool());
assert!(!property_name.is_empty() && !message.is_empty());
Expand All @@ -188,7 +193,7 @@ impl Stmt {
let loc_with_property =
Location::create_location_with_property(message, property_name, loc);

// Chose InternedString to seperate out codegen from the cprover_bindings logic
// Chose InternedString to separate out codegen from the cprover_bindings logic
let property_class = property_name.intern();
let msg = message.into();

Expand Down Expand Up @@ -283,7 +288,7 @@ impl Stmt {
pub fn goto<T: Into<InternedString>>(dest: T, loc: Location) -> Self {
let dest = dest.into();
assert!(!dest.is_empty());
stmt!(Goto(dest), loc)
stmt!(Goto { dest, loop_invariants: None }, loc)
}

/// `if (i) { t } else { e }` or `if (i) { t }`
Expand Down Expand Up @@ -325,6 +330,16 @@ impl Stmt {
assert!(!label.is_empty());
stmt!(Label { label, body: self }, *self.location())
}

/// `goto dest;` with loop invariant
pub fn with_loop_contracts(self, inv: Expr) -> Self {
if let Goto { dest, loop_invariants } = self.body() {
assert!(loop_invariants.is_none());
stmt!(Goto { dest: *dest, loop_invariants: Some(inv) }, *self.location())
} else {
unreachable!("Loop contracts should be annotated only to goto stmt")
}
}
}

/// Predicates
Expand Down
14 changes: 12 additions & 2 deletions cprover_bindings/src/irep/to_irep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,18 @@ impl ToIrep for StmtBody {
arguments_irep(arguments.iter(), mm),
],
),
StmtBody::Goto(dest) => code_irep(IrepId::Goto, vec![])
.with_named_sub(IrepId::Destination, Irep::just_string_id(dest.to_string())),
StmtBody::Goto { dest, loop_invariants } => {
let stmt_goto = code_irep(IrepId::Goto, vec![])
.with_named_sub(IrepId::Destination, Irep::just_string_id(dest.to_string()));
if let Some(inv) = loop_invariants {
stmt_goto.with_named_sub(
IrepId::CSpecLoopInvariant,
inv.clone().and(Expr::bool_true()).to_irep(mm),
)
} else {
stmt_goto
}
}
StmtBody::Ifthenelse { i, t, e } => code_irep(
IrepId::Ifthenelse,
vec![
Expand Down
2 changes: 2 additions & 0 deletions kani-compiler/src/codegen_cprover_gotoc/overrides/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! It would be too nasty if we spread around these sort of undocumented hooks in place, so
//! this module addresses this issue.

use super::loop_contracts_hooks::LoopInvariantRegister;
use crate::codegen_cprover_gotoc::codegen::{bb_label, PropertyClass};
use crate::codegen_cprover_gotoc::GotocCtx;
use crate::kani_middle::attributes::matches_diagnostic as matches_function;
Expand Down Expand Up @@ -555,6 +556,7 @@ pub fn fn_hooks() -> GotocHooks {
Rc::new(MemCmp),
Rc::new(UntrackedDeref),
Rc::new(InitContracts),
Rc::new(LoopInvariantRegister),
],
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

use super::hooks::GotocHook;
use crate::codegen_cprover_gotoc::codegen::bb_label;
use crate::codegen_cprover_gotoc::GotocCtx;
use crate::kani_middle::attributes::KaniAttributes;
use cbmc::goto_program::{CIntType, Expr, Stmt, Type};
use rustc_middle::ty::TyCtxt;
use rustc_span::Symbol;
use stable_mir::mir::mono::Instance;
use stable_mir::mir::{BasicBlockIdx, Place};
use stable_mir::ty::Span;

pub struct LoopInvariantRegister;

impl GotocHook for LoopInvariantRegister {
qinheping marked this conversation as resolved.
Show resolved Hide resolved
fn hook_applies(&self, tcx: TyCtxt, instance: Instance) -> bool {
KaniAttributes::for_instance(tcx, instance).fn_marker()
== Some(Symbol::intern("kani_register_loop_contract"))
}

fn handle(
&self,
gcx: &mut GotocCtx,
instance: Instance,
fargs: Vec<Expr>,
_assign_to: &Place,
target: Option<BasicBlockIdx>,
span: Span,
) -> Stmt {
let loc = gcx.codegen_span_stable(span);
let func_exp = gcx.codegen_func_expr(instance, loc);
Stmt::goto(bb_label(target.unwrap()), loc)
.with_loop_contracts(func_exp.call(fargs).cast_to(Type::CInteger(CIntType::Bool)))
}
}
1 change: 1 addition & 0 deletions kani-compiler/src/codegen_cprover_gotoc/overrides/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
//! Instead, we use a "hook" to generate the correct CBMC intrinsic.

mod hooks;
mod loop_contracts_hooks;

pub use hooks::{fn_hooks, GotocHooks};
Loading
Loading