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 14, 2024
1 parent f158600 commit a690710
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 8 deletions.
16 changes: 11 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,17 @@ 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.
// A potential future alternative would be to resurrect this as a zero-sized allocation
// (which codegen will then compile to an aligned dummy pointer anyway).
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
2 changes: 1 addition & 1 deletion tests/ui/consts/dangling-alloc-id-ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ union Foo<'a> {
}

const FOO: &() = {
//~^ ERROR encountered dangling pointer
//~^ ERROR it is undefined behavior to use this value
let y = ();
unsafe { Foo { y: &y }.long_live_the_unit }
};
Expand Down
10 changes: 8 additions & 2 deletions tests/ui/consts/dangling-alloc-id-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
error: encountered dangling pointer in final value of constant
error[E0080]: it is undefined behavior to use this value
--> $DIR/dangling-alloc-id-ice.rs:12:1
|
LL | const FOO: &() = {
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ 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`.
15 changes: 15 additions & 0 deletions tests/ui/consts/dangling-zst-ice-issue-126393.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/dangling-zst-ice-issue-126393.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/dangling-zst-ice-issue-126393.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 a690710

Please sign in to comment.