11
11
use crate :: codegen_cprover_gotoc:: codegen:: { PropertyClass , bb_label} ;
12
12
use crate :: codegen_cprover_gotoc:: { GotocCtx , utils} ;
13
13
use 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 } ;
15
15
use crate :: unwrap_or_return_codegen_unimplemented_stmt;
16
16
use cbmc:: goto_program:: CIntType ;
17
17
use cbmc:: goto_program:: Symbol as GotoSymbol ;
@@ -30,7 +30,13 @@ use tracing::debug;
30
30
31
31
pub trait GotocHook {
32
32
/// 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 ;
34
40
/// the handler for codegen
35
41
fn handle (
36
42
& self ,
@@ -56,7 +62,13 @@ struct Cover;
56
62
const UNEXPECTED_CALL : & str = "Hooks from kani library handled as a map" ;
57
63
58
64
impl 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 {
60
72
unreachable ! ( "{UNEXPECTED_CALL}" )
61
73
}
62
74
@@ -91,7 +103,13 @@ impl GotocHook for Cover {
91
103
92
104
struct Assume ;
93
105
impl 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 {
95
113
unreachable ! ( "{UNEXPECTED_CALL}" )
96
114
}
97
115
@@ -115,7 +133,13 @@ impl GotocHook for Assume {
115
133
116
134
struct Assert ;
117
135
impl 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 {
119
143
unreachable ! ( "{UNEXPECTED_CALL}" )
120
144
}
121
145
@@ -150,7 +174,13 @@ impl GotocHook for Assert {
150
174
151
175
struct UnsupportedCheck ;
152
176
impl 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 {
154
184
unreachable ! ( "{UNEXPECTED_CALL}" )
155
185
}
156
186
@@ -187,7 +217,13 @@ impl GotocHook for UnsupportedCheck {
187
217
188
218
struct SafetyCheck ;
189
219
impl 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 {
191
227
unreachable ! ( "{UNEXPECTED_CALL}" )
192
228
}
193
229
@@ -218,7 +254,13 @@ impl GotocHook for SafetyCheck {
218
254
219
255
struct SafetyCheckNoAssume ;
220
256
impl 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 {
222
264
unreachable ! ( "{UNEXPECTED_CALL}" )
223
265
}
224
266
@@ -250,7 +292,13 @@ impl GotocHook for SafetyCheckNoAssume {
250
292
// TODO: Remove this and replace occurrences with `SanityCheck`.
251
293
struct Check ;
252
294
impl 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 {
254
302
unreachable ! ( "{UNEXPECTED_CALL}" )
255
303
}
256
304
@@ -286,7 +334,13 @@ impl GotocHook for Check {
286
334
struct Nondet ;
287
335
288
336
impl 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 {
290
344
unreachable ! ( "{UNEXPECTED_CALL}" )
291
345
}
292
346
@@ -325,9 +379,14 @@ impl GotocHook for Nondet {
325
379
struct Panic ;
326
380
327
381
impl 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 {
329
389
let def_id = rustc_internal:: internal ( tcx, instance. def . def_id ( ) ) ;
330
- let kani_tool_attr = attributes:: fn_marker ( instance. def ) ;
331
390
332
391
// we check the attributes to make sure this hook applies to
333
392
// panic functions we've stubbed too
@@ -354,7 +413,13 @@ impl GotocHook for Panic {
354
413
/// Encodes __CPROVER_r_ok(ptr, size)
355
414
struct IsAllocated ;
356
415
impl 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 {
358
423
unreachable ! ( "{UNEXPECTED_CALL}" )
359
424
}
360
425
@@ -393,7 +458,13 @@ impl GotocHook for IsAllocated {
393
458
/// independent of the backend
394
459
struct FloatToIntInRange ;
395
460
impl 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 {
397
468
unreachable ! ( "{UNEXPECTED_CALL}" )
398
469
}
399
470
@@ -438,7 +509,13 @@ impl GotocHook for FloatToIntInRange {
438
509
/// Encodes __CPROVER_pointer_object(ptr)
439
510
struct PointerObject ;
440
511
impl 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 {
442
519
unreachable ! ( "{UNEXPECTED_CALL}" )
443
520
}
444
521
@@ -474,7 +551,13 @@ impl GotocHook for PointerObject {
474
551
/// Encodes __CPROVER_pointer_offset(ptr)
475
552
struct PointerOffset ;
476
553
impl 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 {
478
561
unreachable ! ( "{UNEXPECTED_CALL}" )
479
562
}
480
563
@@ -511,9 +594,14 @@ struct RustAlloc;
511
594
// Removing this hook causes regression failures.
512
595
// https://github.com/model-checking/kani/issues/1170
513
596
impl 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"
517
605
}
518
606
519
607
fn handle (
@@ -562,9 +650,14 @@ impl GotocHook for RustAlloc {
562
650
pub struct MemCmp ;
563
651
564
652
impl 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"
568
661
}
569
662
570
663
fn handle (
@@ -620,7 +713,13 @@ impl GotocHook for MemCmp {
620
713
struct UntrackedDeref ;
621
714
622
715
impl 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 {
624
723
unreachable ! ( "{UNEXPECTED_CALL}" )
625
724
}
626
725
@@ -668,7 +767,13 @@ struct InitContracts;
668
767
/// free(NULL);
669
768
/// ```
670
769
impl 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 {
672
777
unreachable ! ( "{UNEXPECTED_CALL}" )
673
778
}
674
779
@@ -710,9 +815,14 @@ impl GotocHook for InitContracts {
710
815
pub struct LoopInvariantRegister ;
711
816
712
817
impl 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" )
716
826
}
717
827
718
828
fn handle (
@@ -785,7 +895,13 @@ enum QuantifierKind {
785
895
}
786
896
787
897
impl 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 {
789
905
unreachable ! ( "{UNEXPECTED_CALL}" )
790
906
}
791
907
@@ -803,7 +919,13 @@ impl GotocHook for Forall {
803
919
}
804
920
805
921
impl 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 {
807
929
unreachable ! ( "{UNEXPECTED_CALL}" )
808
930
}
809
931
@@ -951,15 +1073,21 @@ pub struct GotocHooks {
951
1073
952
1074
impl GotocHooks {
953
1075
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 ( ) ) ;
961
1089
}
962
- None
963
1090
}
1091
+ None
964
1092
}
965
1093
}
0 commit comments