Skip to content

Commit 198df9e

Browse files
authored
Rollup merge of rust-lang#143595 - fee1-dead-contrib:push-sylpykzkmynr, r=RalfJung,fee1-dead
add `const_make_global`; err for `const_allocate` ptrs if didn't call Implements as discussed on Zulip: [#t-compiler/const-eval > const heap](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/const.20heap/with/527125421) r? ```@rust-lang/wg-const-eval``` Fixes rust-lang#129233
2 parents 5795086 + 0bf0860 commit 198df9e

38 files changed

+413
-105
lines changed

compiler/rustc_const_eval/messages.ftl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ const_eval_const_context = {$kind ->
5656
*[other] {""}
5757
}
5858
59+
const_eval_const_heap_ptr_in_final = encountered `const_allocate` pointer in final value that was not made global
60+
.note = use `const_make_global` to make allocated pointers immutable before returning
61+
62+
const_eval_const_make_global_ptr_already_made_global = attempting to call `const_make_global` twice on the same allocation {$alloc}
63+
64+
const_eval_const_make_global_ptr_is_non_heap = pointer passed to `const_make_global` does not point to a heap allocation: {$ptr}
65+
66+
const_eval_const_make_global_with_dangling_ptr = pointer passed to `const_make_global` is dangling: {$ptr}
67+
68+
const_eval_const_make_global_with_offset = making {$ptr} global which does not point to the beginning of an object
69+
5970
const_eval_copy_nonoverlapping_overlapping =
6071
`copy_nonoverlapping` called on overlapping ranges
6172

compiler/rustc_const_eval/src/const_eval/dummy_machine.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ impl HasStaticRootDefId for DummyMachine {
4949

5050
impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
5151
interpret::compile_time_machine!(<'tcx>);
52-
type MemoryKind = !;
5352
const PANIC_ON_ALLOC_FAIL: bool = true;
5453

5554
// We want to just eval random consts in the program, so `eval_mir_const` can fail.

compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::mem;
22

33
use rustc_errors::{Diag, DiagArgName, DiagArgValue, DiagMessage, IntoDiagArg};
44
use rustc_middle::mir::AssertKind;
5-
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
5+
use rustc_middle::mir::interpret::{AllocId, Provenance, ReportedErrorInfo};
66
use rustc_middle::query::TyCtxtAt;
77
use rustc_middle::ty::layout::LayoutError;
88
use rustc_middle::ty::{ConstInt, TyCtxt};
@@ -11,8 +11,8 @@ use rustc_span::{Span, Symbol};
1111
use super::CompileTimeMachine;
1212
use crate::errors::{self, FrameNote, ReportErrorExt};
1313
use crate::interpret::{
14-
ErrorHandled, Frame, InterpErrorInfo, InterpErrorKind, MachineStopType, err_inval,
15-
err_machine_stop,
14+
CtfeProvenance, ErrorHandled, Frame, InterpErrorInfo, InterpErrorKind, MachineStopType,
15+
Pointer, err_inval, err_machine_stop,
1616
};
1717

1818
/// The CTFE machine has some custom error kinds.
@@ -22,8 +22,22 @@ pub enum ConstEvalErrKind {
2222
ModifiedGlobal,
2323
RecursiveStatic,
2424
AssertFailure(AssertKind<ConstInt>),
25-
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
25+
Panic {
26+
msg: Symbol,
27+
line: u32,
28+
col: u32,
29+
file: Symbol,
30+
},
2631
WriteThroughImmutablePointer,
32+
/// Called `const_make_global` twice.
33+
ConstMakeGlobalPtrAlreadyMadeGlobal(AllocId),
34+
/// Called `const_make_global` on a non-heap pointer.
35+
ConstMakeGlobalPtrIsNonHeap(Pointer<Option<CtfeProvenance>>),
36+
/// Called `const_make_global` on a dangling pointer.
37+
ConstMakeGlobalWithDanglingPtr(Pointer<Option<CtfeProvenance>>),
38+
/// Called `const_make_global` on a pointer that does not start at the
39+
/// beginning of an object.
40+
ConstMakeGlobalWithOffset(Pointer<Option<CtfeProvenance>>),
2741
}
2842

2943
impl MachineStopType for ConstEvalErrKind {
@@ -38,6 +52,12 @@ impl MachineStopType for ConstEvalErrKind {
3852
RecursiveStatic => const_eval_recursive_static,
3953
AssertFailure(x) => x.diagnostic_message(),
4054
WriteThroughImmutablePointer => const_eval_write_through_immutable_pointer,
55+
ConstMakeGlobalPtrAlreadyMadeGlobal { .. } => {
56+
const_eval_const_make_global_ptr_already_made_global
57+
}
58+
ConstMakeGlobalPtrIsNonHeap(_) => const_eval_const_make_global_ptr_is_non_heap,
59+
ConstMakeGlobalWithDanglingPtr(_) => const_eval_const_make_global_with_dangling_ptr,
60+
ConstMakeGlobalWithOffset(_) => const_eval_const_make_global_with_offset,
4161
}
4262
}
4363
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) {
@@ -51,6 +71,14 @@ impl MachineStopType for ConstEvalErrKind {
5171
Panic { msg, .. } => {
5272
adder("msg".into(), msg.into_diag_arg(&mut None));
5373
}
74+
ConstMakeGlobalPtrIsNonHeap(ptr)
75+
| ConstMakeGlobalWithOffset(ptr)
76+
| ConstMakeGlobalWithDanglingPtr(ptr) => {
77+
adder("ptr".into(), format!("{ptr:?}").into_diag_arg(&mut None));
78+
}
79+
ConstMakeGlobalPtrAlreadyMadeGlobal(alloc) => {
80+
adder("alloc".into(), alloc.into_diag_arg(&mut None));
81+
}
5482
}
5583
}
5684
}

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use tracing::{debug, instrument, trace};
1818
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
1919
use crate::const_eval::CheckAlignment;
2020
use crate::interpret::{
21-
CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpErrorKind,
21+
CtfeValidationMode, GlobalId, Immediate, InternError, InternKind, InterpCx, InterpErrorKind,
2222
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, ReturnContinuation, create_static_alloc,
2323
intern_const_alloc_recursive, interp_ok, throw_exhaust,
2424
};
@@ -93,25 +93,30 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
9393
// Since evaluation had no errors, validate the resulting constant.
9494
const_validate_mplace(ecx, &ret, cid)?;
9595

96-
// Only report this after validation, as validaiton produces much better diagnostics.
96+
// Only report this after validation, as validation produces much better diagnostics.
9797
// FIXME: ensure validation always reports this and stop making interning care about it.
9898

9999
match intern_result {
100100
Ok(()) => {}
101-
Err(InternResult::FoundDanglingPointer) => {
101+
Err(InternError::DanglingPointer) => {
102102
throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
103103
ecx.tcx
104104
.dcx()
105105
.emit_err(errors::DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind }),
106106
)));
107107
}
108-
Err(InternResult::FoundBadMutablePointer) => {
108+
Err(InternError::BadMutablePointer) => {
109109
throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
110110
ecx.tcx
111111
.dcx()
112112
.emit_err(errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }),
113113
)));
114114
}
115+
Err(InternError::ConstAllocNotGlobal) => {
116+
throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
117+
ecx.tcx.dcx().emit_err(errors::ConstHeapPtrInFinal { span: ecx.tcx.span }),
118+
)));
119+
}
115120
}
116121

117122
interp_ok(R::make_result(ret, ecx))

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,19 @@ pub type CompileTimeInterpCx<'tcx> = InterpCx<'tcx, CompileTimeMachine<'tcx>>;
169169

170170
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
171171
pub enum MemoryKind {
172-
Heap,
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 {
176180
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177181
match self {
178-
MemoryKind::Heap => write!(f, "heap allocation"),
182+
MemoryKind::Heap { was_made_global } => {
183+
write!(f, "heap allocation{}", if *was_made_global { " (made global)" } else { "" })
184+
}
179185
}
180186
}
181187
}
@@ -184,7 +190,7 @@ impl interpret::MayLeak for MemoryKind {
184190
#[inline(always)]
185191
fn may_leak(self) -> bool {
186192
match self {
187-
MemoryKind::Heap => false,
193+
MemoryKind::Heap { was_made_global } => was_made_global,
188194
}
189195
}
190196
}
@@ -314,8 +320,6 @@ impl<'tcx> CompileTimeMachine<'tcx> {
314320
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
315321
compile_time_machine!(<'tcx>);
316322

317-
type MemoryKind = MemoryKind;
318-
319323
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
320324

321325
#[inline(always)]
@@ -420,7 +424,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
420424
let ptr = ecx.allocate_ptr(
421425
Size::from_bytes(size),
422426
align,
423-
interpret::MemoryKind::Machine(MemoryKind::Heap),
427+
interpret::MemoryKind::Machine(MemoryKind::Heap { was_made_global: false }),
424428
AllocInit::Uninit,
425429
)?;
426430
ecx.write_pointer(ptr, dest)?;
@@ -453,10 +457,17 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
453457
ecx.deallocate_ptr(
454458
ptr,
455459
Some((size, align)),
456-
interpret::MemoryKind::Machine(MemoryKind::Heap),
460+
interpret::MemoryKind::Machine(MemoryKind::Heap { was_made_global: false }),
457461
)?;
458462
}
459463
}
464+
465+
sym::const_make_global => {
466+
let ptr = ecx.read_pointer(&args[0])?;
467+
ecx.make_const_heap_ptr_global(ptr)?;
468+
ecx.write_pointer(ptr, dest)?;
469+
}
470+
460471
// The intrinsic represents whether the value is known to the optimizer (LLVM).
461472
// We're not doing any optimizations here, so there is no optimizer that could know the value.
462473
// (We know the value here in the machine of course, but this is the runtime of that code,

compiler/rustc_const_eval/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ pub(crate) struct MutablePtrInFinal {
4343
pub kind: InternKind,
4444
}
4545

46+
#[derive(Diagnostic)]
47+
#[diag(const_eval_const_heap_ptr_in_final)]
48+
#[note]
49+
pub(crate) struct ConstHeapPtrInFinal {
50+
#[primary_span]
51+
pub span: Span,
52+
}
53+
4654
#[derive(Diagnostic)]
4755
#[diag(const_eval_unstable_in_stable_exposed)]
4856
pub(crate) struct UnstableInStableExposed {

0 commit comments

Comments
 (0)