Skip to content

Commit

Permalink
Rollup merge of #70947 - RalfJung:ctfe-no-read-mut-global, r=oli-obk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Dylan-DPC authored Apr 14, 2020
2 parents 15ab586 + a1f7e9a commit b5dc6e6
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions src/librustc_mir/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
static_def_id: Option<DefId>,
is_write: bool,
) -> InterpResult<'tcx> {
if is_write && allocation.mutability == Mutability::Not {
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
} else if is_write {
Err(ConstEvalErrKind::ModifiedGlobal.into())
} else if memory_extra.can_access_statics || static_def_id.is_none() {
// `static_def_id.is_none()` indicates this is not a static, but a const or so.
Ok(())
if is_write {
// Write access. These are never allowed, but we give a targeted error message.
if allocation.mutability == Mutability::Not {
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
} else {
Err(ConstEvalErrKind::ModifiedGlobal.into())
}
} else {
Err(ConstEvalErrKind::ConstAccessesStatic.into())
// Read access. These are usually allowed, with some exceptions.
if memory_extra.can_access_statics {
// Machine configuration allows us read from anything (e.g., `static` initializer).
Ok(())
} else if static_def_id.is_some() {
// Machine configuration does not allow us to read statics
// (e.g., `const` initializer).
Err(ConstEvalErrKind::ConstAccessesStatic.into())
} else {
// Immutable global, this read is fine.
// But make sure we never accept a read from something mutable, that would be
// unsound. The reason is that as the content of this allocation may be different
// now and at run-time, so if we permit reading now we might return the wrong value.
assert_eq!(allocation.mutability, Mutability::Not);
Ok(())
}
}
}
}
Expand Down

0 comments on commit b5dc6e6

Please sign in to comment.