Skip to content

Commit b5dc6e6

Browse files
authored
Rollup merge of #70947 - RalfJung:ctfe-no-read-mut-global, r=oli-obk
tighten CTFE safety net for accesses to globals Previously, we only rejected reading from all statics. Now we also reject reading from any mutable global. Mutable globals are the true culprit here as their run-time value might be different from their compile-time values. Statics are just the approximation we use for that so far. Also refactor the code a bit to make it clearer what is being checked and allowed. r? @oli-obk
2 parents 15ab586 + a1f7e9a commit b5dc6e6

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

src/librustc_mir/const_eval/machine.rs

+23-8
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
353353
static_def_id: Option<DefId>,
354354
is_write: bool,
355355
) -> InterpResult<'tcx> {
356-
if is_write && allocation.mutability == Mutability::Not {
357-
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
358-
} else if is_write {
359-
Err(ConstEvalErrKind::ModifiedGlobal.into())
360-
} else if memory_extra.can_access_statics || static_def_id.is_none() {
361-
// `static_def_id.is_none()` indicates this is not a static, but a const or so.
362-
Ok(())
356+
if is_write {
357+
// Write access. These are never allowed, but we give a targeted error message.
358+
if allocation.mutability == Mutability::Not {
359+
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
360+
} else {
361+
Err(ConstEvalErrKind::ModifiedGlobal.into())
362+
}
363363
} else {
364-
Err(ConstEvalErrKind::ConstAccessesStatic.into())
364+
// Read access. These are usually allowed, with some exceptions.
365+
if memory_extra.can_access_statics {
366+
// Machine configuration allows us read from anything (e.g., `static` initializer).
367+
Ok(())
368+
} else if static_def_id.is_some() {
369+
// Machine configuration does not allow us to read statics
370+
// (e.g., `const` initializer).
371+
Err(ConstEvalErrKind::ConstAccessesStatic.into())
372+
} else {
373+
// Immutable global, this read is fine.
374+
// But make sure we never accept a read from something mutable, that would be
375+
// unsound. The reason is that as the content of this allocation may be different
376+
// now and at run-time, so if we permit reading now we might return the wrong value.
377+
assert_eq!(allocation.mutability, Mutability::Not);
378+
Ok(())
379+
}
365380
}
366381
}
367382
}

0 commit comments

Comments
 (0)