Skip to content

Commit 91fd8a9

Browse files
committed
Override std::ptr::align_offset
This hook intercepts calls to `std::ptr::align_offset<T>` as CBMC's memory model has no concept of alignment of allocations, so we would have to non-deterministically choose an alignment of the base pointer, add the pointer's offset to it, and then do the math that is done in `library/core/src/ptr/mod.rs`. Instead, we choose to always return `usize::MAX`, per `align_offset`'s documentation, which states: "It is permissible for the implementation to always return usize::MAX. Only your algorithm’s performance can depend on getting a usable offset here, not its correctness." Fixes: #2363
1 parent 173594b commit 91fd8a9

File tree

1 file changed

+36
-0
lines changed
  • kani-compiler/src/codegen_cprover_gotoc/overrides

1 file changed

+36
-0
lines changed

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,41 @@ fn find_closure_call_expr(instance: &Instance, gcx: &mut GotocCtx, loc: Location
908908
None
909909
}
910910

911+
/// This hook intercepts calls to `std::ptr::align_offset<T>` as CBMC's memory model has no concept
912+
/// of alignment of allocations, so we would have to non-deterministically choose an alignment of
913+
/// the base pointer, add the pointer's offset to it, and then do the math that is done in
914+
/// `library/core/src/ptr/mod.rs`. Instead, we choose to always return `usize::MAX`, per
915+
/// `align_offset`'s documentation, which states: "It is permissible for the implementation to
916+
/// always return usize::MAX. Only your algorithm’s performance can depend on getting a usable
917+
/// offset here, not its correctness."
918+
pub struct AlignOffset;
919+
920+
impl<'tcx> GotocHook<'tcx> for AlignOffset {
921+
fn hook_applies(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
922+
let name = with_no_trimmed_paths!(tcx.def_path_str(instance.def_id()));
923+
name == "std::ptr::align_offset"
924+
}
925+
926+
fn handle(
927+
&self,
928+
tcx: &mut GotocCtx<'tcx>,
929+
_instance: Instance<'tcx>,
930+
mut _fargs: Vec<Expr>,
931+
assign_to: Place<'tcx>,
932+
target: Option<BasicBlock>,
933+
span: Option<Span>,
934+
) -> Stmt {
935+
let loc = tcx.codegen_span_option(span);
936+
let target = target.unwrap();
937+
let place_expr =
938+
unwrap_or_return_codegen_unimplemented_stmt!(tcx, tcx.codegen_place(&assign_to))
939+
.goto_expr;
940+
let rhs = Expr::int_constant(usize::MAX, place_expr.typ().clone());
941+
let code = place_expr.assign(rhs, loc).with_location(loc);
942+
Stmt::block(vec![code, Stmt::goto(tcx.current_fn().find_label(&target), loc)], loc)
943+
}
944+
}
945+
911946
pub fn fn_hooks() -> GotocHooks {
912947
let kani_lib_hooks = [
913948
(KaniHook::Assert, Rc::new(Assert) as Rc<dyn GotocHook>),
@@ -935,6 +970,7 @@ pub fn fn_hooks() -> GotocHooks {
935970
Rc::new(RustAlloc),
936971
Rc::new(MemCmp),
937972
Rc::new(LoopInvariantRegister),
973+
Rc::new(AlignOffset),
938974
],
939975
}
940976
}

0 commit comments

Comments
 (0)