Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5d328a1

Browse files
committedMay 22, 2024
Auto merge of #117329 - RalfJung:offset-by-zero, r=oli-obk,scottmcm
offset: allow zero-byte offset on arbitrary pointers As per prior `@rust-lang/opsem` [discussion](rust-lang/opsem-team#10) and [FCP](rust-lang/unsafe-code-guidelines#472 (comment)): - Zero-sized reads and writes are allowed on all sufficiently aligned pointers, including the null pointer - Inbounds-offset-by-zero is allowed on all pointers, including the null pointer - `offset_from` on two pointers derived from the same allocation is always allowed when they have the same address This removes surprising UB (in particular, even C++ allows "nullptr + 0", which we currently disallow), and it brings us one step closer to an important theoretical property for our semantics ("provenance monotonicity": if operations are valid on bytes without provenance, then adding provenance can't make them invalid). The minimum LLVM we require (v17) includes https://reviews.llvm.org/D154051, so we can finally implement this. The `offset_from` change is needed to maintain the equivalence with `offset`: if `let ptr2 = ptr1.offset(N)` is well-defined, then `ptr2.offset_from(ptr1)` should be well-defined and return N. Now consider the case where N is 0 and `ptr1` dangles: we want to still allow offset_from here. I think we should change offset_from further, but that's a separate discussion. Fixes #65108 [Tracking issue](#117945) | [T-lang summary](#117329 (comment)) Cc `@nikic`
2 parents f0038a7 + 9526ce6 commit 5d328a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+202
-476
lines changed
 

‎compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use rustc_target::spec::abi::Abi as CallAbi;
2525
use crate::errors::{LongRunning, LongRunningWarn};
2626
use crate::fluent_generated as fluent;
2727
use crate::interpret::{
28-
self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom,
28+
self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom, throw_unsup,
2929
throw_unsup_format, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, Frame,
30-
ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar,
30+
GlobalAlloc, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar,
3131
};
3232

3333
use super::error::*;
@@ -759,11 +759,21 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
759759
ecx: &InterpCx<'mir, 'tcx, Self>,
760760
alloc_id: AllocId,
761761
) -> InterpResult<'tcx> {
762+
// Check if this is the currently evaluated static.
762763
if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) {
763-
Err(ConstEvalErrKind::RecursiveStatic.into())
764-
} else {
765-
Ok(())
764+
return Err(ConstEvalErrKind::RecursiveStatic.into());
766765
}
766+
// If this is another static, make sure we fire off the query to detect cycles.
767+
// But only do that when checks for static recursion are enabled.
768+
if ecx.machine.static_root_ids.is_some() {
769+
if let Some(GlobalAlloc::Static(def_id)) = ecx.tcx.try_get_global_alloc(alloc_id) {
770+
if ecx.tcx.is_foreign_item(def_id) {
771+
throw_unsup!(ExternStatic(def_id));
772+
}
773+
ecx.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
774+
}
775+
}
776+
Ok(())
767777
}
768778
}
769779

‎compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
255255
name = intrinsic_name,
256256
);
257257
}
258+
// This will always return 0.
258259
(a, b)
259260
}
260261
(Err(_), _) | (_, Err(_)) => {

0 commit comments

Comments
 (0)
Please sign in to comment.