diff --git a/rust-version b/rust-version index 9782fbe6cd..4577339061 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -cdcc53b7dc002ea4a7a28105010c5a1126ee31b7 +a09c668c965f735f4cd59e7158662b9daa0b71ba diff --git a/src/machine.rs b/src/machine.rs index 824f0e3fc8..d14ddaa1a6 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -618,7 +618,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> { id: AllocId, alloc: Cow<'b, Allocation>, kind: Option>, - ) -> Cow<'b, Allocation> { + ) -> InterpResult<'tcx, Cow<'b, Allocation>> { if ecx.machine.tracked_alloc_ids.contains(&id) { register_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id)); } @@ -653,15 +653,28 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> { data_race: race_alloc, weak_memory: buffer_alloc, }, - |ptr| Evaluator::tag_alloc_base_pointer(ecx, ptr), - ); - Cow::Owned(alloc) + |ptr| ecx.global_base_pointer(ptr), + )?; + Ok(Cow::Owned(alloc)) } fn tag_alloc_base_pointer( ecx: &MiriEvalContext<'mir, 'tcx>, ptr: Pointer, ) -> Pointer { + if cfg!(debug_assertions) { + // The machine promises to never call us on thread-local or extern statics. + let alloc_id = ptr.provenance; + match ecx.tcx.get_global_alloc(alloc_id) { + Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_thread_local_static(def_id) => { + panic!("tag_alloc_base_pointer called on thread-local static") + } + Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_foreign_item(def_id) => { + panic!("tag_alloc_base_pointer called on extern static") + } + _ => {} + } + } let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr); let sb_tag = if let Some(stacked_borrows) = &ecx.machine.stacked_borrows { stacked_borrows.borrow_mut().base_tag(ptr.provenance) diff --git a/src/thread.rs b/src/thread.rs index 9eabbd7741..2135806de3 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -587,7 +587,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // This allocation will be deallocated when the thread dies, so it is not in read-only memory. allocation.mutability = Mutability::Mut; // Create a fresh allocation with this content. - let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into()); + let new_alloc = this.allocate_raw_ptr(allocation, MiriMemoryKind::Tls.into())?; this.machine.threads.set_thread_local_alloc(def_id, new_alloc); Ok(new_alloc) } diff --git a/tests/fail/extern_static_in_const.rs b/tests/fail/extern_static_in_const.rs new file mode 100644 index 0000000000..4c1de6ace5 --- /dev/null +++ b/tests/fail/extern_static_in_const.rs @@ -0,0 +1,11 @@ +//! Even referencing an unknown `extern static` already triggers an error. + +extern "C" { + static E: [u8; 0]; +} + +static X: &'static [u8; 0] = unsafe { &E }; + +fn main() { + let _val = X; //~ ERROR is not supported by Miri +} diff --git a/tests/fail/extern_static_in_const.stderr b/tests/fail/extern_static_in_const.stderr new file mode 100644 index 0000000000..8524bb02c0 --- /dev/null +++ b/tests/fail/extern_static_in_const.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: `extern` static `E` from crate `extern_static_in_const` is not supported by Miri + --> $DIR/extern_static_in_const.rs:LL:CC + | +LL | let _val = X; + | ^ `extern` static `E` from crate `extern_static_in_const` is not supported by Miri + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + + = note: inside `main` at $DIR/extern_static_in_const.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error +