Skip to content

Commit f834be7

Browse files
JustusAdamcelinvalfeliperodri
authored
Function Contracts: Support for defining and checking requires and ensures clauses (rust-lang#2655)
Co-authored-by: Celina G. Val <[email protected]> Co-authored-by: Felipe R. Monteiro <[email protected]>
1 parent 9cd3de1 commit f834be7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1478
-20
lines changed

kani-compiler/src/codegen_cprover_gotoc/overrides/hooks.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,49 @@ impl<'tcx> GotocHook<'tcx> for MemCmp {
325325
}
326326
}
327327

328+
/// A builtin that is essentially a C-style dereference operation, creating an
329+
/// unsafe shallow copy. Importantly either this copy or the original needs to
330+
/// be `mem::forget`en or a double-free will occur.
331+
///
332+
/// Takes in a `&T` reference and returns a `T` (like clone would but without
333+
/// cloning). Breaks ownership rules and is only used in the context of function
334+
/// contracts where we can structurally guarantee the use is safe.
335+
struct UntrackedDeref;
336+
337+
impl<'tcx> GotocHook<'tcx> for UntrackedDeref {
338+
fn hook_applies(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
339+
matches_function(tcx, instance, "KaniUntrackedDeref")
340+
}
341+
342+
fn handle(
343+
&self,
344+
tcx: &mut GotocCtx<'tcx>,
345+
_instance: Instance<'tcx>,
346+
mut fargs: Vec<Expr>,
347+
assign_to: Place<'tcx>,
348+
_target: Option<BasicBlock>,
349+
span: Option<Span>,
350+
) -> Stmt {
351+
assert_eq!(
352+
fargs.len(),
353+
1,
354+
"Invariant broken. `untracked_deref` should only be given one argument. \
355+
This function should only be called from code generated by kani macros, \
356+
as such this is likely a code-generation error."
357+
);
358+
let loc = tcx.codegen_span_option(span);
359+
Stmt::block(
360+
vec![Stmt::assign(
361+
unwrap_or_return_codegen_unimplemented_stmt!(tcx, tcx.codegen_place(&assign_to))
362+
.goto_expr,
363+
fargs.pop().unwrap().dereference(),
364+
loc,
365+
)],
366+
loc,
367+
)
368+
}
369+
}
370+
328371
pub fn fn_hooks<'tcx>() -> GotocHooks<'tcx> {
329372
GotocHooks {
330373
hooks: vec![
@@ -335,6 +378,7 @@ pub fn fn_hooks<'tcx>() -> GotocHooks<'tcx> {
335378
Rc::new(Nondet),
336379
Rc::new(RustAlloc),
337380
Rc::new(MemCmp),
381+
Rc::new(UntrackedDeref),
338382
],
339383
}
340384
}

0 commit comments

Comments
 (0)