]> git.lizzy.rs Git - rust.git/blobdiff - src/eval.rs
Adjust Miri to also require return places everywhere
[rust.git] / src / eval.rs
index 24a0fc8ef161791c5cbdc1389a32b9deeb0d1f31..badda8f3bc3938910a652087d0970a1c2be100cf 100644 (file)
@@ -113,9 +113,11 @@ pub struct MiriConfig {
     pub panic_on_unsupported: bool,
     /// Which style to use for printing backtraces.
     pub backtrace_style: BacktraceStyle,
-    /// Whether to enforce "strict provenance" rules. Enabling this means int2ptr casts return
-    /// pointers with an invalid provenance, i.e., not valid for any memory access.
-    pub strict_provenance: bool,
+    /// Which provenance to use for int2ptr casts
+    pub provenance_mode: ProvenanceMode,
+    /// Whether to ignore any output by the program. This is helpful when debugging miri
+    /// as its messages don't get intermingled with the program messages.
+    pub mute_stdout_stderr: bool,
 }
 
 impl Default for MiriConfig {
@@ -132,16 +134,17 @@ fn default() -> MiriConfig {
             forwarded_env_vars: vec![],
             args: vec![],
             seed: None,
-            tracked_pointer_tags: Default::default(),
-            tracked_call_ids: Default::default(),
-            tracked_alloc_ids: Default::default(),
+            tracked_pointer_tags: HashSet::default(),
+            tracked_call_ids: HashSet::default(),
+            tracked_alloc_ids: HashSet::default(),
             tag_raw: false,
             data_race_detector: true,
             cmpxchg_weak_failure_rate: 0.8,
             measureme_out: None,
             panic_on_unsupported: false,
             backtrace_style: BacktraceStyle::Short,
-            strict_provenance: false,
+            provenance_mode: ProvenanceMode::Legacy,
+            mute_stdout_stderr: false,
         }
     }
 }
@@ -164,19 +167,28 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
         param_env,
         Evaluator::new(config, layout_cx),
     );
+
+    // Capture the current interpreter stack state (which should be empty) so that we can emit
+    // allocation-tracking and tag-tracking diagnostics for allocations which are part of the
+    // early runtime setup.
+    let info = ecx.preprocess_diagnostics();
+
     // Some parts of initialization require a full `InterpCx`.
     Evaluator::late_init(&mut ecx, config)?;
 
     // Make sure we have MIR. We check MIR for some stable monomorphic function in libcore.
-    let sentinel = ecx.resolve_path(&["core", "ascii", "escape_default"]);
-    if !tcx.is_mir_available(sentinel.def.def_id()) {
-        tcx.sess.fatal("the current sysroot was built without `-Zalways-encode-mir`. Use `cargo miri setup` to prepare a sysroot that is suitable for Miri.");
+    let sentinel = ecx.try_resolve_path(&["core", "ascii", "escape_default"]);
+    if !matches!(sentinel, Some(s) if tcx.is_mir_available(s.def.def_id())) {
+        tcx.sess.fatal(
+            "the current sysroot was built without `-Zalways-encode-mir`, or libcore seems missing. \
+            Use `cargo miri setup` to prepare a sysroot that is suitable for Miri."
+        );
     }
 
-    // Setup first stack-frame
+    // Setup first stack frame.
     let entry_instance = ty::Instance::mono(tcx, entry_id);
 
-    // First argument is constructed later, because its skipped if the entry function uses #[start]
+    // First argument is constructed later, because it's skipped if the entry function uses #[start].
 
     // Second argument (argc): length of `config.args`.
     let argc = Scalar::from_machine_usize(u64::try_from(config.args.len()).unwrap(), &ecx);
@@ -265,7 +277,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
                 start_instance,
                 Abi::Rust,
                 &[Scalar::from_pointer(main_ptr, &ecx).into(), argc.into(), argv],
-                Some(&ret_place.into()),
+                &ret_place.into(),
                 StackPopCleanup::Root { cleanup: true },
             )?;
         }
@@ -274,12 +286,16 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
                 entry_instance,
                 Abi::Rust,
                 &[argc.into(), argv],
-                Some(&ret_place.into()),
+                &ret_place.into(),
                 StackPopCleanup::Root { cleanup: true },
             )?;
         }
     }
 
+    // Emit any diagnostics related to the setup process for the runtime, so that when the
+    // interpreter loop starts there are no unprocessed diagnostics.
+    ecx.process_diagnostics(info);
+
     Ok((ecx, ret_place))
 }
 
@@ -337,7 +353,12 @@ pub fn eval_entry<'tcx>(
     })();
 
     // Machine cleanup.
-    EnvVars::cleanup(&mut ecx).unwrap();
+    // Execution of the program has halted so any memory access we do here
+    // cannot produce a real data race. If we do not do something to disable
+    // data race detection here, some uncommon combination of errors will
+    // cause a data race to be detected:
+    // https://github.com/rust-lang/miri/issues/2020
+    ecx.allow_data_races_mut(|ecx| EnvVars::cleanup(ecx).unwrap());
 
     // Process the result.
     match res {