summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-14 12:23:38 +0200
committerGitHub <noreply@github.com>2024-06-14 12:23:38 +0200
commitaebd794d15cfea87a1c7abd711a8b3f7dc3d0a35 (patch)
tree8bfba41f510851ef680dd6b23d5f2f6dd1549457 /compiler/rustc_const_eval/src/interpret
parentb7dcdf684c93a9691bc6ce1a7f5a71b56cd04374 (diff)
parenta6907100de23e51ba979ead543fcd5975d62d248 (diff)
downloadrust-aebd794d15cfea87a1c7abd711a8b3f7dc3d0a35.tar.gz
rust-aebd794d15cfea87a1c7abd711a8b3f7dc3d0a35.zip
Rollup merge of #126426 - RalfJung:dangling-zst-ice, r=oli-obk
const validation: fix ICE on dangling ZST reference

Fixes https://github.com/rust-lang/rust/issues/126393
I'm not super happy with this fix but I can't think of a better one.

r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs16
1 files changed, 11 insertions, 5 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 6f75bc2af4e..ca8b9884933 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -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,
 };
@@ -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,
             },
@@ -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.