1111use crate :: codegen_cprover_gotoc:: codegen:: { PropertyClass , bb_label} ;
1212use crate :: codegen_cprover_gotoc:: { GotocCtx , utils} ;
1313use crate :: kani_middle:: attributes;
14- use crate :: kani_middle:: kani_functions:: { KaniFunction , KaniHook } ;
14+ use crate :: kani_middle:: kani_functions:: { KaniFunction , KaniHook , try_get_kani_function } ;
1515use crate :: unwrap_or_return_codegen_unimplemented_stmt;
1616use cbmc:: goto_program:: CIntType ;
1717use cbmc:: goto_program:: Symbol as GotoSymbol ;
@@ -30,7 +30,13 @@ use tracing::debug;
3030
3131pub trait GotocHook {
3232 /// if the hook applies, it means the codegen would do something special to it
33- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool ;
33+ fn hook_applies (
34+ & self ,
35+ _tcx : TyCtxt ,
36+ _instance : Instance ,
37+ _instance_name : & str ,
38+ _kani_tool_attr : Option < & String > ,
39+ ) -> bool ;
3440 /// the handler for codegen
3541 fn handle (
3642 & self ,
@@ -56,7 +62,13 @@ struct Cover;
5662const UNEXPECTED_CALL : & str = "Hooks from kani library handled as a map" ;
5763
5864impl GotocHook for Cover {
59- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
65+ fn hook_applies (
66+ & self ,
67+ _tcx : TyCtxt ,
68+ _instance : Instance ,
69+ _instance_name : & str ,
70+ _kani_tool_attr : Option < & String > ,
71+ ) -> bool {
6072 unreachable ! ( "{UNEXPECTED_CALL}" )
6173 }
6274
@@ -91,7 +103,13 @@ impl GotocHook for Cover {
91103
92104struct Assume ;
93105impl GotocHook for Assume {
94- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
106+ fn hook_applies (
107+ & self ,
108+ _tcx : TyCtxt ,
109+ _instance : Instance ,
110+ _instance_name : & str ,
111+ _kani_tool_attr : Option < & String > ,
112+ ) -> bool {
95113 unreachable ! ( "{UNEXPECTED_CALL}" )
96114 }
97115
@@ -115,7 +133,13 @@ impl GotocHook for Assume {
115133
116134struct Assert ;
117135impl GotocHook for Assert {
118- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
136+ fn hook_applies (
137+ & self ,
138+ _tcx : TyCtxt ,
139+ _instance : Instance ,
140+ _instance_name : & str ,
141+ _kani_tool_attr : Option < & String > ,
142+ ) -> bool {
119143 unreachable ! ( "{UNEXPECTED_CALL}" )
120144 }
121145
@@ -150,7 +174,13 @@ impl GotocHook for Assert {
150174
151175struct UnsupportedCheck ;
152176impl GotocHook for UnsupportedCheck {
153- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
177+ fn hook_applies (
178+ & self ,
179+ _tcx : TyCtxt ,
180+ _instance : Instance ,
181+ _instance_name : & str ,
182+ _kani_tool_attr : Option < & String > ,
183+ ) -> bool {
154184 unreachable ! ( "{UNEXPECTED_CALL}" )
155185 }
156186
@@ -187,7 +217,13 @@ impl GotocHook for UnsupportedCheck {
187217
188218struct SafetyCheck ;
189219impl GotocHook for SafetyCheck {
190- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
220+ fn hook_applies (
221+ & self ,
222+ _tcx : TyCtxt ,
223+ _instance : Instance ,
224+ _instance_name : & str ,
225+ _kani_tool_attr : Option < & String > ,
226+ ) -> bool {
191227 unreachable ! ( "{UNEXPECTED_CALL}" )
192228 }
193229
@@ -218,7 +254,13 @@ impl GotocHook for SafetyCheck {
218254
219255struct SafetyCheckNoAssume ;
220256impl GotocHook for SafetyCheckNoAssume {
221- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
257+ fn hook_applies (
258+ & self ,
259+ _tcx : TyCtxt ,
260+ _instance : Instance ,
261+ _instance_name : & str ,
262+ _kani_tool_attr : Option < & String > ,
263+ ) -> bool {
222264 unreachable ! ( "{UNEXPECTED_CALL}" )
223265 }
224266
@@ -250,7 +292,13 @@ impl GotocHook for SafetyCheckNoAssume {
250292// TODO: Remove this and replace occurrences with `SanityCheck`.
251293struct Check ;
252294impl GotocHook for Check {
253- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
295+ fn hook_applies (
296+ & self ,
297+ _tcx : TyCtxt ,
298+ _instance : Instance ,
299+ _instance_name : & str ,
300+ _kani_tool_attr : Option < & String > ,
301+ ) -> bool {
254302 unreachable ! ( "{UNEXPECTED_CALL}" )
255303 }
256304
@@ -286,7 +334,13 @@ impl GotocHook for Check {
286334struct Nondet ;
287335
288336impl GotocHook for Nondet {
289- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
337+ fn hook_applies (
338+ & self ,
339+ _tcx : TyCtxt ,
340+ _instance : Instance ,
341+ _instance_name : & str ,
342+ _kani_tool_attr : Option < & String > ,
343+ ) -> bool {
290344 unreachable ! ( "{UNEXPECTED_CALL}" )
291345 }
292346
@@ -325,9 +379,14 @@ impl GotocHook for Nondet {
325379struct Panic ;
326380
327381impl GotocHook for Panic {
328- fn hook_applies ( & self , tcx : TyCtxt , instance : Instance ) -> bool {
382+ fn hook_applies (
383+ & self ,
384+ tcx : TyCtxt ,
385+ instance : Instance ,
386+ _instance_name : & str ,
387+ kani_tool_attr : Option < & String > ,
388+ ) -> bool {
329389 let def_id = rustc_internal:: internal ( tcx, instance. def . def_id ( ) ) ;
330- let kani_tool_attr = attributes:: fn_marker ( instance. def ) ;
331390
332391 // we check the attributes to make sure this hook applies to
333392 // panic functions we've stubbed too
@@ -354,7 +413,13 @@ impl GotocHook for Panic {
354413/// Encodes __CPROVER_r_ok(ptr, size)
355414struct IsAllocated ;
356415impl GotocHook for IsAllocated {
357- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
416+ fn hook_applies (
417+ & self ,
418+ _tcx : TyCtxt ,
419+ _instance : Instance ,
420+ _instance_name : & str ,
421+ _kani_tool_attr : Option < & String > ,
422+ ) -> bool {
358423 unreachable ! ( "{UNEXPECTED_CALL}" )
359424 }
360425
@@ -393,7 +458,13 @@ impl GotocHook for IsAllocated {
393458/// independent of the backend
394459struct FloatToIntInRange ;
395460impl GotocHook for FloatToIntInRange {
396- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
461+ fn hook_applies (
462+ & self ,
463+ _tcx : TyCtxt ,
464+ _instance : Instance ,
465+ _instance_name : & str ,
466+ _kani_tool_attr : Option < & String > ,
467+ ) -> bool {
397468 unreachable ! ( "{UNEXPECTED_CALL}" )
398469 }
399470
@@ -438,7 +509,13 @@ impl GotocHook for FloatToIntInRange {
438509/// Encodes __CPROVER_pointer_object(ptr)
439510struct PointerObject ;
440511impl GotocHook for PointerObject {
441- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
512+ fn hook_applies (
513+ & self ,
514+ _tcx : TyCtxt ,
515+ _instance : Instance ,
516+ _instance_name : & str ,
517+ _kani_tool_attr : Option < & String > ,
518+ ) -> bool {
442519 unreachable ! ( "{UNEXPECTED_CALL}" )
443520 }
444521
@@ -474,7 +551,13 @@ impl GotocHook for PointerObject {
474551/// Encodes __CPROVER_pointer_offset(ptr)
475552struct PointerOffset ;
476553impl GotocHook for PointerOffset {
477- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
554+ fn hook_applies (
555+ & self ,
556+ _tcx : TyCtxt ,
557+ _instance : Instance ,
558+ _instance_name : & str ,
559+ _kani_tool_attr : Option < & String > ,
560+ ) -> bool {
478561 unreachable ! ( "{UNEXPECTED_CALL}" )
479562 }
480563
@@ -511,9 +594,14 @@ struct RustAlloc;
511594// Removing this hook causes regression failures.
512595// https://github.com/model-checking/kani/issues/1170
513596impl GotocHook for RustAlloc {
514- fn hook_applies ( & self , _tcx : TyCtxt , instance : Instance ) -> bool {
515- let full_name = instance. name ( ) ;
516- full_name == "alloc::alloc::exchange_malloc"
597+ fn hook_applies (
598+ & self ,
599+ _tcx : TyCtxt ,
600+ _instance : Instance ,
601+ instance_name : & str ,
602+ _kani_tool_attr : Option < & String > ,
603+ ) -> bool {
604+ instance_name == "alloc::alloc::exchange_malloc"
517605 }
518606
519607 fn handle (
@@ -562,9 +650,14 @@ impl GotocHook for RustAlloc {
562650pub struct MemCmp ;
563651
564652impl GotocHook for MemCmp {
565- fn hook_applies ( & self , _tcx : TyCtxt , instance : Instance ) -> bool {
566- let name = instance. name ( ) ;
567- name == "core::slice::cmp::memcmp" || name == "std::slice::cmp::memcmp"
653+ fn hook_applies (
654+ & self ,
655+ _tcx : TyCtxt ,
656+ _instance : Instance ,
657+ instance_name : & str ,
658+ _kani_tool_attr : Option < & String > ,
659+ ) -> bool {
660+ instance_name == "core::slice::cmp::memcmp" || instance_name == "std::slice::cmp::memcmp"
568661 }
569662
570663 fn handle (
@@ -620,7 +713,13 @@ impl GotocHook for MemCmp {
620713struct UntrackedDeref ;
621714
622715impl GotocHook for UntrackedDeref {
623- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
716+ fn hook_applies (
717+ & self ,
718+ _tcx : TyCtxt ,
719+ _instance : Instance ,
720+ _instance_name : & str ,
721+ _kani_tool_attr : Option < & String > ,
722+ ) -> bool {
624723 unreachable ! ( "{UNEXPECTED_CALL}" )
625724 }
626725
@@ -668,7 +767,13 @@ struct InitContracts;
668767/// free(NULL);
669768/// ```
670769impl GotocHook for InitContracts {
671- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
770+ fn hook_applies (
771+ & self ,
772+ _tcx : TyCtxt ,
773+ _instance : Instance ,
774+ _instance_name : & str ,
775+ _kani_tool_attr : Option < & String > ,
776+ ) -> bool {
672777 unreachable ! ( "{UNEXPECTED_CALL}" )
673778 }
674779
@@ -710,9 +815,14 @@ impl GotocHook for InitContracts {
710815pub struct LoopInvariantRegister ;
711816
712817impl GotocHook for LoopInvariantRegister {
713- fn hook_applies ( & self , _tcx : TyCtxt , instance : Instance ) -> bool {
714- attributes:: fn_marker ( instance. def )
715- . is_some_and ( |marker| marker == "kani_register_loop_contract" )
818+ fn hook_applies (
819+ & self ,
820+ _tcx : TyCtxt ,
821+ _instance : Instance ,
822+ _instance_name : & str ,
823+ kani_tool_attr : Option < & String > ,
824+ ) -> bool {
825+ kani_tool_attr. is_some_and ( |marker| marker == "kani_register_loop_contract" )
716826 }
717827
718828 fn handle (
@@ -785,7 +895,13 @@ enum QuantifierKind {
785895}
786896
787897impl GotocHook for Forall {
788- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
898+ fn hook_applies (
899+ & self ,
900+ _tcx : TyCtxt ,
901+ _instance : Instance ,
902+ _instance_name : & str ,
903+ _kani_tool_attr : Option < & String > ,
904+ ) -> bool {
789905 unreachable ! ( "{UNEXPECTED_CALL}" )
790906 }
791907
@@ -803,7 +919,13 @@ impl GotocHook for Forall {
803919}
804920
805921impl GotocHook for Exists {
806- fn hook_applies ( & self , _tcx : TyCtxt , _instance : Instance ) -> bool {
922+ fn hook_applies (
923+ & self ,
924+ _tcx : TyCtxt ,
925+ _instance : Instance ,
926+ _instance_name : & str ,
927+ _kani_tool_attr : Option < & String > ,
928+ ) -> bool {
807929 unreachable ! ( "{UNEXPECTED_CALL}" )
808930 }
809931
@@ -951,15 +1073,21 @@ pub struct GotocHooks {
9511073
9521074impl GotocHooks {
9531075 pub fn hook_applies ( & self , tcx : TyCtxt , instance : Instance ) -> Option < Rc < dyn GotocHook > > {
954- if let Ok ( KaniFunction :: Hook ( hook) ) = KaniFunction :: try_from ( instance) {
955- Some ( self . kani_lib_hooks [ & hook] . clone ( ) )
956- } else {
957- for h in & self . other_hooks {
958- if h. hook_applies ( tcx, instance) {
959- return Some ( h. clone ( ) ) ;
960- }
1076+ let fn_attr = attributes:: fn_marker ( instance. def ) ;
1077+ if let Some ( ref fn_attr) = fn_attr
1078+ && let Some ( KaniFunction :: Hook ( hook) ) = try_get_kani_function ( fn_attr)
1079+ {
1080+ return Some ( self . kani_lib_hooks [ & hook] . clone ( ) ) ;
1081+ }
1082+
1083+ let instance_name = instance. name ( ) ;
1084+ let kani_tool_attr = fn_attr. as_ref ( ) ;
1085+
1086+ for h in & self . other_hooks {
1087+ if h. hook_applies ( tcx, instance, & instance_name, kani_tool_attr) {
1088+ return Some ( h. clone ( ) ) ;
9611089 }
962- None
9631090 }
1091+ None
9641092 }
9651093}
0 commit comments