Skip to content

Commit fd48b7b

Browse files
fee1-deadRalfJung
andcommitted
Comment more code and make tests clearer
Co-Authored-By: Ralf Jung <post@ralfj.de>
1 parent 44b38ca commit fd48b7b

18 files changed

+49
-32
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ pub type CompileTimeInterpCx<'tcx> = InterpCx<'tcx, CompileTimeMachine<'tcx>>;
169169

170170
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
171171
pub enum MemoryKind {
172-
Heap { was_made_global: bool },
172+
Heap {
173+
/// Indicates whether `make_global` was called on this allocation.
174+
/// If this is `true`, the allocation must be immutable.
175+
was_made_global: bool,
176+
},
173177
}
174178

175179
impl fmt::Display for MemoryKind {

compiler/rustc_const_eval/src/interpret/intern.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,12 @@ fn intern_shallow<'tcx, T: CanIntern, M: CompileTimeMachine<'tcx, T>>(
106106

107107
match kind {
108108
MemoryKind::Machine(x) if let Some(reason) = x.disallows_intern() => match reason {
109-
// attempting to intern a `const_allocate`d pointer that was not made global via
110-
// `const_make_global`. We emit an error here but don't return an `Err`. The `Err`
111-
// is for pointers that we can't intern at all (i.e. dangling pointers). We still
112-
// (recursively) intern this pointer because we don't have to worry about the
113-
// additional paperwork involved with _not_ interning it, such as storing it in
114-
// the dead memory map and having to deal with additional "dangling pointer"
115-
// messages if someone tries to store the non-made-global ptr in the final value.
109+
// Attempting to intern a `const_allocate`d pointer that was not made global via
110+
// `const_make_global`. This is an error, but if we return `Err` now, things
111+
// become inconsistent because we already removed the allocation from `alloc_map`.
112+
// So instead we just emit an error and then continue interning as usual.
113+
// We *could* do this check before removing the allocation from `alloc_map`, but then
114+
// it would be much harder to ensure that we only error once for each allocation.
116115
DisallowInternReason::ConstHeap => {
117116
ecx.tcx.dcx().emit_err(ConstHeapPtrInFinal { span: ecx.tcx.span });
118117
}

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
312312
interp_ok(new_ptr)
313313
}
314314

315-
/// mark the `const_allocate`d pointer immutable so we can intern it.
315+
/// Mark the `const_allocate`d allocation `ptr` points to as immutable so we can intern it.
316316
pub fn make_const_heap_ptr_global(
317317
&mut self,
318318
ptr: Pointer<Option<CtfeProvenance>>,
@@ -325,20 +325,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
325325
return Err(ConstEvalErrKind::ConstMakeGlobalWithOffset(ptr)).into();
326326
}
327327

328-
let not_local_heap =
329-
matches!(self.tcx.try_get_global_alloc(alloc_id), Some(GlobalAlloc::Memory(_)));
330-
331-
if not_local_heap {
328+
if matches!(self.tcx.try_get_global_alloc(alloc_id), Some(_)) {
329+
// This points to something outside the current interpreter.
332330
return Err(ConstEvalErrKind::ConstMakeGlobalPtrIsNonHeap(ptr)).into();
333331
}
334332

333+
// If we can't find it in `alloc_map` it must be dangling (because we don't use
334+
// `extra_fn_ptr_map` in const-eval).
335335
let (kind, alloc) = self
336336
.memory
337337
.alloc_map
338338
.get_mut_or(alloc_id, || Err(ConstEvalErrKind::ConstMakeGlobalWithDanglingPtr(ptr)))?;
339339

340-
alloc.mutability = Mutability::Not;
341-
340+
// Ensure this is actually a *heap* allocation, and record it as made-global.
342341
match kind {
343342
MemoryKind::Stack | MemoryKind::CallerLocation => {
344343
return Err(ConstEvalErrKind::ConstMakeGlobalPtrIsNonHeap(ptr)).into();
@@ -352,6 +351,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
352351
}
353352
}
354353

354+
// Prevent further mutation, this is now an immutable global.
355+
alloc.mutability = Mutability::Not;
356+
355357
interp_ok(())
356358
}
357359

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ fn check_validity_requirement_strict<'tcx>(
5252

5353
let mut cx = InterpCx::new(cx.tcx(), DUMMY_SP, cx.typing_env, machine);
5454

55+
// It doesn't really matter which `MemoryKind` we use here, `Stack` is the least wrong.
5556
let allocated =
5657
cx.allocate(ty, MemoryKind::Stack).expect("OOM: failed to allocate for uninit check");
5758

@@ -183,12 +184,10 @@ pub(crate) fn validate_scalar_in_layout<'tcx>(
183184
let Ok(layout) = cx.layout_of(ty) else {
184185
bug!("could not compute layout of {scalar:?}:{ty:?}")
185186
};
186-
let allocated = cx
187-
.allocate(
188-
layout,
189-
MemoryKind::Machine(crate::const_eval::MemoryKind::Heap { was_made_global: false }),
190-
)
191-
.expect("OOM: failed to allocate for uninit check");
187+
188+
// It doesn't really matter which `MemoryKind` we use here, `Stack` is the least wrong.
189+
let allocated =
190+
cx.allocate(layout, MemoryKind::Stack).expect("OOM: failed to allocate for uninit check");
192191

193192
cx.write_scalar(scalar, &allocated).unwrap();
194193

tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const fn foo() -> &'static i32 {
1212
*i = 20;
1313
i
1414
};
15-
unsafe { &*(intrinsics::const_make_global(t as *mut u8) as *mut i32) }
15+
unsafe { &*(intrinsics::const_make_global(t as *mut u8) as *const i32) }
1616
}
1717
fn main() {
1818
assert_eq!(*FOO, 20);

tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::intrinsics;
66

77
const BAR: &i32 = unsafe { //~ ERROR: uninitialized memory
8-
&*(intrinsics::const_make_global(intrinsics::const_allocate(4, 4)) as *mut i32)
8+
// Make the pointer immutable to avoid errors related to mutable pointers in constants.
9+
&*(intrinsics::const_make_global(intrinsics::const_allocate(4, 4)) as *const i32)
910
};
1011
fn main() {}

tests/ui/consts/const-eval/heap/make-global-dangling.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Ensure that we can't call `const_make_global` on dangling pointers.
2+
13
#![feature(core_intrinsics)]
24
#![feature(const_heap)]
35

tests/ui/consts/const-eval/heap/make-global-dangling.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got null pointer
2-
--> $DIR/make-global-dangling.rs:7:8
2+
--> $DIR/make-global-dangling.rs:9:8
33
|
44
LL | &*(intrinsics::const_make_global(std::ptr::null_mut()) as *const u32)
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here
66

77
error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got 0x1[noalloc] which is a dangling pointer (it has no provenance)
8-
--> $DIR/make-global-dangling.rs:12:8
8+
--> $DIR/make-global-dangling.rs:14:8
99
|
1010
LL | &*(intrinsics::const_make_global(std::ptr::dangling_mut()) as *const u32)
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Z` failed here

tests/ui/consts/const-eval/heap/make-global-other.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Ensure that we can't call `const_make_global` on pointers not in the current interpreter.
2+
13
#![feature(core_intrinsics)]
24
#![feature(const_heap)]
35

tests/ui/consts/const-eval/heap/make-global-other.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: pointer passed to `const_make_global` does not point to a heap allocation: ALLOC0<imm>
2-
--> $DIR/make-global-other.rs:9:8
2+
--> $DIR/make-global-other.rs:11:8
33
|
44
LL | &*(intrinsics::const_make_global(X as *const i32 as *mut u8) as *const i32)
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here

0 commit comments

Comments
 (0)