Panic on mutable allocs in constants

This commit is contained in:
Oliver Scherer 2019-12-16 15:23:26 +01:00
parent a916ac22b9
commit 640e2884ad
3 changed files with 59 additions and 6 deletions

View File

@ -320,12 +320,19 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
// We can't call the `intern_shallow` method here, as its logic is tailored to safe
// references and a `leftover_allocations` set (where we only have a todo-list here).
// So we hand-roll the interning logic here again.
if base_intern_mode != InternMode::Static {
// If it's not a static, it *must* be immutable.
// We cannot have mutable memory inside a constant.
// FIXME: ideally we would assert that they already are immutable, to double-
// check our static checks.
alloc.mutability = Mutability::Not;
match base_intern_mode {
InternMode::Static => {}
InternMode::Const | InternMode::ConstBase => {
// If it's not a static, it *must* be immutable.
// We cannot have mutable memory inside a constant.
// We use `delay_span_bug` here, because this can be reached in the presence
// of fancy transmutes.
if alloc.mutability == Mutability::Mut {
// For better errors later, mark the allocation as immutable
alloc.mutability = Mutability::Not;
ecx.tcx.sess.delay_span_bug(ecx.tcx.span, "mutable allocation in constant");
}
}
}
let alloc = tcx.intern_const_alloc(alloc);
tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
@ -337,6 +344,8 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
} else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) {
// dangling pointer
throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into()))
} else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() {
span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
}
}
Ok(())

View File

@ -0,0 +1,19 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
// failure-status: 101
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET"
// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS"
// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC"
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
#![deny(const_err)]
use std::cell::UnsafeCell;
// make sure we do not just intern this as mutable
const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
//~^ WARN: skipping const checks
//~| ERROR: mutable allocation in constant
fn main() {}

View File

@ -0,0 +1,25 @@
warning: skipping const checks
--> $DIR/mutable_const2.rs:15:38
|
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: mutable allocation in constant
--> $DIR/mutable_const2.rs:15:1
|
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:347:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc VERSION running on TARGET
note: compiler flags: FLAGS