@@ -28,13 +28,14 @@ use std::env::{self, VarError};
2828use std:: num:: NonZero ;
2929use std:: ops:: Range ;
3030use std:: path:: PathBuf ;
31+ use std:: rc:: Rc ;
3132use std:: str:: FromStr ;
3233use std:: sync:: atomic:: { AtomicI32 , AtomicU32 , Ordering } ;
3334use std:: sync:: { Arc , Once } ;
3435
3536use miri:: {
36- BacktraceStyle , BorrowTrackerMethod , MiriConfig , MiriEntryFnType , ProvenanceMode , RetagFields ,
37- ValidationMode ,
37+ BacktraceStyle , BorrowTrackerMethod , GenmcConfig , GenmcCtx , MiriConfig , MiriEntryFnType ,
38+ ProvenanceMode , RetagFields , ValidationMode ,
3839} ;
3940use rustc_abi:: ExternAbi ;
4041use rustc_data_structures:: sync;
@@ -60,6 +61,8 @@ use tracing::debug;
6061struct MiriCompilerCalls {
6162 miri_config : Option < MiriConfig > ,
6263 many_seeds : Option < ManySeedsConfig > ,
64+ /// Settings for using GenMC with Miri.
65+ genmc_config : Option < GenmcConfig > ,
6366}
6467
6568struct ManySeedsConfig {
@@ -68,8 +71,12 @@ struct ManySeedsConfig {
6871}
6972
7073impl 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 }
7380 }
7481}
7582
@@ -179,6 +186,12 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
179186 optimizations is usually marginal at best.") ;
180187 }
181188
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+
182195 if let Some ( many_seeds) = self . many_seeds . take ( ) {
183196 assert ! ( config. seed. is_none( ) ) ;
184197 let exit_code = sync:: IntoDynSyncSend ( AtomicI32 :: new ( rustc_driver:: EXIT_SUCCESS ) ) ;
@@ -187,8 +200,14 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
187200 let mut config = config. clone ( ) ;
188201 config. seed = Some ( ( * seed) . into ( ) ) ;
189202 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 ) ;
192211 if return_code != rustc_driver:: EXIT_SUCCESS {
193212 eprintln ! ( "FAILING SEED: {seed}" ) ;
194213 if !many_seeds. keep_going {
@@ -206,11 +225,12 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
206225 }
207226 std:: process:: exit ( exit_code. 0 . into_inner ( ) ) ;
208227 } 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 )
210229 . unwrap_or_else ( || {
211230 tcx. dcx ( ) . abort_if_errors ( ) ;
212231 rustc_driver:: EXIT_FAILURE
213232 } ) ;
233+
214234 std:: process:: exit ( return_code) ;
215235 }
216236
@@ -506,6 +526,7 @@ fn main() {
506526 let mut many_seeds_keep_going = false ;
507527 let mut miri_config = MiriConfig :: default ( ) ;
508528 miri_config. env = env_snapshot;
529+ let mut genmc_config = None ;
509530
510531 let mut rustc_args = vec ! [ ] ;
511532 let mut after_dashdash = false ;
@@ -603,6 +624,10 @@ fn main() {
603624 many_seeds = Some ( 0 ..64 ) ;
604625 } else if arg == "-Zmiri-many-seeds-keep-going" {
605626 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) ;
606631 } else if let Some ( param) = arg. strip_prefix ( "-Zmiri-env-forward=" ) {
607632 miri_config. forwarded_env_vars . push ( param. to_owned ( ) ) ;
608633 } else if let Some ( param) = arg. strip_prefix ( "-Zmiri-env-set=" ) {
@@ -697,7 +722,7 @@ fn main() {
697722 rustc_args. push ( arg) ;
698723 }
699724 }
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`.
701726 if miri_config. unique_is_unique
702727 && !matches ! ( miri_config. borrow_tracker, Some ( BorrowTrackerMethod :: TreeBorrows ) )
703728 {
@@ -734,7 +759,24 @@ fn main() {
734759 let many_seeds =
735760 many_seeds. map ( |seeds| ManySeedsConfig { seeds, keep_going : many_seeds_keep_going } ) ;
736761
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+
737776 debug ! ( "rustc arguments: {:?}" , rustc_args) ;
738777 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+ )
740782}
0 commit comments