Skip to content

Commit dcbf10a

Browse files
danielsntedinski
authored andcommitted
Implemented __VERIFIER_assume hook (rust-lang#115)
1 parent 4b69065 commit dcbf10a

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

compiler/rustc_codegen_llvm/src/gotoc/cbmc/goto_program/stmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl Stmt {
187187

188188
/// `__CPROVER_assume(cond);`
189189
pub fn assume(cond: Expr, loc: Location) -> Self {
190-
assert!(cond.typ().is_bool());
190+
assert!(cond.typ().is_bool(), "Assume expected bool, got {:?}", cond);
191191
stmt!(Assume { cond }, loc)
192192
}
193193

compiler/rustc_codegen_llvm/src/gotoc/hooks.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,40 @@ fn sig_of_instance<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::FnS
4848
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig)
4949
}
5050

51+
struct Assume;
52+
impl<'tcx> GotocHook<'tcx> for Assume {
53+
fn hook_applies(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
54+
let sig = sig_of_instance(tcx, instance);
55+
let def_path = tcx.def_path(instance.def.def_id());
56+
if let Some(data) = def_path.data.last() {
57+
match data.data.name() {
58+
DefPathDataName::Named(name) => {
59+
return name.to_string().starts_with("__VERIFIER_assume");
60+
}
61+
DefPathDataName::Anon { .. } => (),
62+
}
63+
}
64+
false
65+
}
66+
67+
fn handle(
68+
&self,
69+
tcx: &mut GotocCtx<'tcx>,
70+
_instance: Instance<'tcx>,
71+
mut fargs: Vec<Expr>,
72+
_assign_to: Option<Place<'tcx>>,
73+
target: Option<BasicBlock>,
74+
span: Option<Span>,
75+
) -> Stmt {
76+
assert_eq!(fargs.len(), 1);
77+
let cond = fargs.remove(0).cast_to(Type::bool());
78+
let target = target.unwrap();
79+
let loc = tcx.codegen_span_option2(span);
80+
81+
Stmt::block(vec![Stmt::assume(cond, loc.clone()), Stmt::goto(tcx.find_label(&target), loc)])
82+
}
83+
}
84+
5185
struct Nondet;
5286

5387
impl<'tcx> GotocHook<'tcx> for Nondet {
@@ -553,6 +587,7 @@ pub fn type_and_fn_hooks<'tcx>() -> (GotocTypeHooks<'tcx>, GotocHooks<'tcx>) {
553587
hooks: vec![
554588
Rc::new(Panic), //Must go first, so it overrides Nevers
555589
Rc::new(Nevers),
590+
Rc::new(Assume),
556591
Rc::new(Nondet),
557592
Rc::new(MemReplace),
558593
Rc::new(MemSwap),

rust-tests/cbmc-reg/Assume/main.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
fn __VERIFIER_assume(cond: bool) {
5+
unimplemented!()
6+
}
7+
8+
fn __nondet<T>() -> T {
9+
unimplemented!()
10+
}
11+
12+
fn main() {
13+
let i: i32 = __nondet();
14+
__VERIFIER_assume(i < 10);
15+
assert!(i < 20);
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
fn __VERIFIER_assume(cond: bool) {
5+
unimplemented!()
6+
}
7+
8+
fn __nondet<T>() -> T {
9+
unimplemented!()
10+
}
11+
12+
fn main() {
13+
let i: i32 = __nondet();
14+
__VERIFIER_assume(i < 10);
15+
assert!(i > 20);
16+
}

0 commit comments

Comments
 (0)