@@ -28,13 +28,14 @@ use std::env::{self, VarError};
28
28
use std:: num:: NonZero ;
29
29
use std:: ops:: Range ;
30
30
use std:: path:: PathBuf ;
31
+ use std:: rc:: Rc ;
31
32
use std:: str:: FromStr ;
32
33
use std:: sync:: atomic:: { AtomicI32 , AtomicU32 , Ordering } ;
33
34
use std:: sync:: { Arc , Once } ;
34
35
35
36
use miri:: {
36
- BacktraceStyle , BorrowTrackerMethod , MiriConfig , MiriEntryFnType , ProvenanceMode , RetagFields ,
37
- ValidationMode ,
37
+ BacktraceStyle , BorrowTrackerMethod , GenmcConfig , GenmcCtx , MiriConfig , MiriEntryFnType ,
38
+ ProvenanceMode , RetagFields , ValidationMode ,
38
39
} ;
39
40
use rustc_abi:: ExternAbi ;
40
41
use rustc_data_structures:: sync;
@@ -60,6 +61,8 @@ use tracing::debug;
60
61
struct MiriCompilerCalls {
61
62
miri_config : Option < MiriConfig > ,
62
63
many_seeds : Option < ManySeedsConfig > ,
64
+ /// Settings for using GenMC with Miri.
65
+ genmc_config : Option < GenmcConfig > ,
63
66
}
64
67
65
68
struct ManySeedsConfig {
@@ -68,8 +71,12 @@ struct ManySeedsConfig {
68
71
}
69
72
70
73
impl MiriCompilerCalls {
71
- fn new ( miri_config : MiriConfig , many_seeds : Option < ManySeedsConfig > ) -> Self {
72
- Self { miri_config : Some ( miri_config) , many_seeds }
74
+ fn new (
75
+ miri_config : MiriConfig ,
76
+ many_seeds : Option < ManySeedsConfig > ,
77
+ genmc_config : Option < GenmcConfig > ,
78
+ ) -> Self {
79
+ Self { miri_config : Some ( miri_config) , many_seeds, genmc_config }
73
80
}
74
81
}
75
82
@@ -179,6 +186,12 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
179
186
optimizations is usually marginal at best.") ;
180
187
}
181
188
189
+ if let Some ( genmc_config) = & self . genmc_config {
190
+ let _genmc_ctx = Rc :: new ( GenmcCtx :: new ( & config, genmc_config) ) ;
191
+
192
+ todo ! ( "GenMC mode not yet implemented" ) ;
193
+ } ;
194
+
182
195
if let Some ( many_seeds) = self . many_seeds . take ( ) {
183
196
assert ! ( config. seed. is_none( ) ) ;
184
197
let exit_code = sync:: IntoDynSyncSend ( AtomicI32 :: new ( rustc_driver:: EXIT_SUCCESS ) ) ;
@@ -187,8 +200,14 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
187
200
let mut config = config. clone ( ) ;
188
201
config. seed = Some ( ( * seed) . into ( ) ) ;
189
202
eprintln ! ( "Trying seed: {seed}" ) ;
190
- let return_code = miri:: eval_entry ( tcx, entry_def_id, entry_type, config)
191
- . unwrap_or ( rustc_driver:: EXIT_FAILURE ) ;
203
+ let return_code = miri:: eval_entry (
204
+ tcx,
205
+ entry_def_id,
206
+ entry_type,
207
+ & config,
208
+ /* genmc_ctx */ None ,
209
+ )
210
+ . unwrap_or ( rustc_driver:: EXIT_FAILURE ) ;
192
211
if return_code != rustc_driver:: EXIT_SUCCESS {
193
212
eprintln ! ( "FAILING SEED: {seed}" ) ;
194
213
if !many_seeds. keep_going {
@@ -206,11 +225,12 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
206
225
}
207
226
std:: process:: exit ( exit_code. 0 . into_inner ( ) ) ;
208
227
} else {
209
- let return_code = miri:: eval_entry ( tcx, entry_def_id, entry_type, config)
228
+ let return_code = miri:: eval_entry ( tcx, entry_def_id, entry_type, & config, None )
210
229
. unwrap_or_else ( || {
211
230
tcx. dcx ( ) . abort_if_errors ( ) ;
212
231
rustc_driver:: EXIT_FAILURE
213
232
} ) ;
233
+
214
234
std:: process:: exit ( return_code) ;
215
235
}
216
236
@@ -506,6 +526,7 @@ fn main() {
506
526
let mut many_seeds_keep_going = false ;
507
527
let mut miri_config = MiriConfig :: default ( ) ;
508
528
miri_config. env = env_snapshot;
529
+ let mut genmc_config = None ;
509
530
510
531
let mut rustc_args = vec ! [ ] ;
511
532
let mut after_dashdash = false ;
@@ -603,6 +624,10 @@ fn main() {
603
624
many_seeds = Some ( 0 ..64 ) ;
604
625
} else if arg == "-Zmiri-many-seeds-keep-going" {
605
626
many_seeds_keep_going = true ;
627
+ } else if let Some ( trimmed_arg) = arg. strip_prefix ( "-Zmiri-genmc" ) {
628
+ // FIXME(GenMC): Currently, GenMC mode is incompatible with aliasing model checking.
629
+ miri_config. borrow_tracker = None ;
630
+ GenmcConfig :: parse_arg ( & mut genmc_config, trimmed_arg) ;
606
631
} else if let Some ( param) = arg. strip_prefix ( "-Zmiri-env-forward=" ) {
607
632
miri_config. forwarded_env_vars . push ( param. to_owned ( ) ) ;
608
633
} else if let Some ( param) = arg. strip_prefix ( "-Zmiri-env-set=" ) {
@@ -697,7 +722,7 @@ fn main() {
697
722
rustc_args. push ( arg) ;
698
723
}
699
724
}
700
- // `-Zmiri-unique-is-unique` should only be used with `-Zmiri-tree-borrows`
725
+ // `-Zmiri-unique-is-unique` should only be used with `-Zmiri-tree-borrows`.
701
726
if miri_config. unique_is_unique
702
727
&& !matches ! ( miri_config. borrow_tracker, Some ( BorrowTrackerMethod :: TreeBorrows ) )
703
728
{
@@ -734,7 +759,24 @@ fn main() {
734
759
let many_seeds =
735
760
many_seeds. map ( |seeds| ManySeedsConfig { seeds, keep_going : many_seeds_keep_going } ) ;
736
761
762
+ // Validate settings for data race detection and GenMC mode.
763
+ assert_eq ! ( genmc_config. is_some( ) , miri_config. genmc_mode) ;
764
+ if genmc_config. is_some ( ) {
765
+ if !miri_config. data_race_detector {
766
+ show_error ! ( "Cannot disable data race detection in GenMC mode (currently)" ) ;
767
+ } else if !miri_config. weak_memory_emulation {
768
+ show_error ! ( "Cannot disable weak memory emulation in GenMC mode" ) ;
769
+ }
770
+ } else if miri_config. weak_memory_emulation && !miri_config. data_race_detector {
771
+ show_error ! (
772
+ "Weak memory emulation cannot be enabled when the data race detector is disabled"
773
+ ) ;
774
+ } ;
775
+
737
776
debug ! ( "rustc arguments: {:?}" , rustc_args) ;
738
777
debug ! ( "crate arguments: {:?}" , miri_config. args) ;
739
- run_compiler_and_exit ( & rustc_args, & mut MiriCompilerCalls :: new ( miri_config, many_seeds) )
778
+ run_compiler_and_exit (
779
+ & rustc_args,
780
+ & mut MiriCompilerCalls :: new ( miri_config, many_seeds, genmc_config) ,
781
+ )
740
782
}
0 commit comments