Skip to content

Commit

Permalink
const validation: fix ICE on dangling ZST reference
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Jun 13, 2024
1 parent f158600 commit ec823b8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
14 changes: 9 additions & 5 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rustc_target::abi::{
use std::hash::Hash;

use super::{
err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, CheckInAllocMsg,
err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, AllocKind, CheckInAllocMsg,
GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
Pointer, Projectable, Scalar, ValueVisitor,
};
Expand Down Expand Up @@ -413,8 +413,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
Ub(PointerOutOfBounds { .. }) => DanglingPtrOutOfBounds {
ptr_kind
},
// This cannot happen during const-eval (because interning already detects
// dangling pointers), but it can happen in Miri.
Ub(PointerUseAfterFree(..)) => DanglingPtrUseAfterFree {
ptr_kind,
},
Expand Down Expand Up @@ -493,9 +491,15 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
}
}

// Mutability check.
// Dangling and Mutability check.
let (size, _align, alloc_kind) = self.ecx.get_alloc_info(alloc_id);
if alloc_kind == AllocKind::Dead {
// This can happen for zero-sized references. We can't have *any* references to non-existing
// allocations though, interning rejects them all as the rest of rustc isn't happy with them...
// so we throw an error, even though this isn't really UB.
throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind });
}
// If this allocation has size zero, there is no actual mutability here.
let (size, _align, _alloc_kind) = self.ecx.get_alloc_info(alloc_id);
if size != Size::ZERO {
let alloc_actual_mutbl = mutability(self.ecx, alloc_id);
// Mutable pointer to immutable memory is no good.
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/consts/issue-126393-dangling-zst-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Strip out raw byte dumps to make comparison platform-independent:
//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP"

pub struct Wrapper;
pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
//~^ERROR: it is undefined behavior to use this value
std::mem::transmute(&{
let y = 42;
y
})
};

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/consts/issue-126393-dangling-zst-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/issue-126393-dangling-zst-ice.rs:7:1
|
LL | pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0080`.

0 comments on commit ec823b8

Please sign in to comment.