Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

const validation: fix ICE on dangling ZST reference #126426

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.
Loading