@@ -325,6 +325,49 @@ impl<'tcx> GotocHook<'tcx> for MemCmp {
325
325
}
326
326
}
327
327
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
+
328
371
pub fn fn_hooks < ' tcx > ( ) -> GotocHooks < ' tcx > {
329
372
GotocHooks {
330
373
hooks : vec ! [
@@ -335,6 +378,7 @@ pub fn fn_hooks<'tcx>() -> GotocHooks<'tcx> {
335
378
Rc :: new( Nondet ) ,
336
379
Rc :: new( RustAlloc ) ,
337
380
Rc :: new( MemCmp ) ,
381
+ Rc :: new( UntrackedDeref ) ,
338
382
] ,
339
383
}
340
384
}
0 commit comments