File tree 7 files changed +46
-11
lines changed
ci/docker/host-x86_64/x86_64-gnu-tools
7 files changed +46
-11
lines changed Original file line number Diff line number Diff line change @@ -40,6 +40,14 @@ if [ -z "${PR_CI_JOB:-}" ]; then
40
40
else
41
41
python3 " $X_PY " test --stage 2 src/tools/miri src/tools/miri/cargo-miri
42
42
fi
43
+ # We re-run the test suite for a chance to find bugs in the intrinsic fallback bodies and in MIR
44
+ # optimizations. This can miss UB, so we only run the "pass" tests. We need to enable debug
45
+ # assertions as `-O` disables them but some tests rely on them. We also set a cfg flag so tests can
46
+ # adjust their expectations if needed. This can change the output of the tests so we ignore that,
47
+ # we only ensure that all assertions still pass.
48
+ MIRIFLAGS=" -Zmiri-force-intrinsic-fallback --cfg force_intrinsic_fallback -O -Zmir-opt-level=4 -Cdebug-assertions=yes" \
49
+ MIRI_SKIP_UI_CHECKS=1 \
50
+ python3 " $X_PY " test --stage 2 src/tools/miri -- tests/{pass,panic}
43
51
# We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
44
52
# Also cover some other targets via cross-testing, in particular all tier 1 targets.
45
53
case $HOST_TARGET in
Original file line number Diff line number Diff line change @@ -393,6 +393,9 @@ to Miri failing to detect cases of undefined behavior in a program.
393
393
disables the randomization of the next thread to be picked, instead fixing a round-robin schedule.
394
394
Note however that other aspects of Miri's concurrency behavior are still randomize; use
395
395
` -Zmiri-deterministic-concurrency` to disable them all.
396
+ * `-Zmiri-force-intrinsic-fallback` forces the use of the "fallback" body for all intrinsics that
397
+ have one. This is useful to test the fallback bodies, but should not be used otherwise. It is
398
+ **unsound** since the fallback body might not be checking for all UB.
396
399
* `-Zmiri-native-lib=<path to a shared object file>` is an experimental flag for providing support
397
400
for calling native functions from inside the interpreter via FFI. The flag is supported only on
398
401
Unix systems. Functions not provided by that file are still executed via the usual Miri shims.
Original file line number Diff line number Diff line change @@ -584,6 +584,8 @@ fn main() {
584
584
} else if arg == "-Zmiri-ignore-leaks" {
585
585
miri_config. ignore_leaks = true ;
586
586
miri_config. collect_leak_backtraces = false ;
587
+ } else if arg == "-Zmiri-force-intrinsic-fallback" {
588
+ miri_config. force_intrinsic_fallback = true ;
587
589
} else if arg == "-Zmiri-strict-provenance" {
588
590
miri_config. provenance_mode = ProvenanceMode :: Strict ;
589
591
} else if arg == "-Zmiri-permissive-provenance" {
Original file line number Diff line number Diff line change @@ -165,6 +165,8 @@ pub struct MiriConfig {
165
165
pub address_reuse_cross_thread_rate : f64 ,
166
166
/// Round Robin scheduling with no preemption.
167
167
pub fixed_scheduling : bool ,
168
+ /// Always prefer the intrinsic fallback body over the native Miri implementation.
169
+ pub force_intrinsic_fallback : bool ,
168
170
}
169
171
170
172
impl Default for MiriConfig {
@@ -203,6 +205,7 @@ impl Default for MiriConfig {
203
205
address_reuse_rate : 0.5 ,
204
206
address_reuse_cross_thread_rate : 0.1 ,
205
207
fixed_scheduling : false ,
208
+ force_intrinsic_fallback : false ,
206
209
}
207
210
}
208
211
}
Original file line number Diff line number Diff line change @@ -28,6 +28,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
28
28
) -> InterpResult < ' tcx , Option < ty:: Instance < ' tcx > > > {
29
29
let this = self . eval_context_mut ( ) ;
30
30
31
+ // Force use of fallback body, if available.
32
+ if this. machine . force_intrinsic_fallback
33
+ && !this. tcx . intrinsic ( instance. def_id ( ) ) . unwrap ( ) . must_be_overridden
34
+ {
35
+ return interp_ok ( Some ( ty:: Instance {
36
+ def : ty:: InstanceKind :: Item ( instance. def_id ( ) ) ,
37
+ args : instance. args ,
38
+ } ) ) ;
39
+ }
40
+
31
41
// See if the core engine can handle this intrinsic.
32
42
if this. eval_intrinsic ( instance, args, dest, ret) ? {
33
43
return interp_ok ( None ) ;
Original file line number Diff line number Diff line change @@ -614,6 +614,9 @@ pub struct MiriMachine<'tcx> {
614
614
615
615
/// Cache for `mangle_internal_symbol`.
616
616
pub ( crate ) mangle_internal_symbol_cache : FxHashMap < & ' static str , String > ,
617
+
618
+ /// Always prefer the intrinsic fallback body over the native Miri implementation.
619
+ pub force_intrinsic_fallback : bool ,
617
620
}
618
621
619
622
impl < ' tcx > MiriMachine < ' tcx > {
@@ -770,6 +773,7 @@ impl<'tcx> MiriMachine<'tcx> {
770
773
reject_in_isolation_warned : Default :: default ( ) ,
771
774
int2ptr_warned : Default :: default ( ) ,
772
775
mangle_internal_symbol_cache : Default :: default ( ) ,
776
+ force_intrinsic_fallback : config. force_intrinsic_fallback ,
773
777
}
774
778
}
775
779
@@ -946,6 +950,7 @@ impl VisitProvenance for MiriMachine<'_> {
946
950
reject_in_isolation_warned : _,
947
951
int2ptr_warned : _,
948
952
mangle_internal_symbol_cache : _,
953
+ force_intrinsic_fallback : _,
949
954
} = self ;
950
955
951
956
threads. visit_provenance ( visit) ;
Original file line number Diff line number Diff line change @@ -33,20 +33,24 @@ fn main() {
33
33
assert_eq ! ( intrinsics:: likely( false ) , false ) ;
34
34
assert_eq ! ( intrinsics:: unlikely( true ) , true ) ;
35
35
36
- let mut saw_true = false ;
37
- let mut saw_false = false ;
36
+ // Skip this test when we use the fallback bodies, as that one is deterministic.
37
+ // (CI sets `--cfg force_intrinsic_fallback` together with `-Zmiri-force-intrinsic-fallback`.)
38
+ if !cfg ! ( force_intrinsic_fallback) {
39
+ let mut saw_true = false ;
40
+ let mut saw_false = false ;
38
41
39
- for _ in 0 ..50 {
40
- if intrinsics:: is_val_statically_known ( 0 ) {
41
- saw_true = true ;
42
- } else {
43
- saw_false = true ;
42
+ for _ in 0 ..50 {
43
+ if intrinsics:: is_val_statically_known ( 0 ) {
44
+ saw_true = true ;
45
+ } else {
46
+ saw_false = true ;
47
+ }
44
48
}
49
+ assert ! (
50
+ saw_true && saw_false,
51
+ "`is_val_statically_known` failed to return both true and false. Congrats, you won the lottery!"
52
+ ) ;
45
53
}
46
- assert ! (
47
- saw_true && saw_false,
48
- "`is_val_statically_known` failed to return both true and false. Congrats, you won the lottery!"
49
- ) ;
50
54
51
55
intrinsics:: forget ( Bomb ) ;
52
56
You can’t perform that action at this time.
0 commit comments