const validation: properly ignore zero-sized UnsafeCell
This commit is contained in:
parent
bc4376fa73
commit
3790eff4d4
2 changed files with 29 additions and 3 deletions
|
|
@ -1086,8 +1086,13 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
|
|||
) -> InterpResult<'tcx> {
|
||||
// Special check for CTFE validation, preventing `UnsafeCell` inside unions in immutable memory.
|
||||
if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) {
|
||||
if !val.layout.is_zst() && !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env)
|
||||
{
|
||||
// Unsized unions are currently not a thing, but let's keep this code consistent with
|
||||
// the check in `visit_value`.
|
||||
let zst = self
|
||||
.ecx
|
||||
.size_and_align_of(&val.meta(), &val.layout)?
|
||||
.is_some_and(|(s, _a)| s.bytes() == 0);
|
||||
if !zst && !val.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.typing_env) {
|
||||
if !self.in_mutable_memory(val) {
|
||||
throw_validation_failure!(self.path, UnsafeCellInImmutable);
|
||||
}
|
||||
|
|
@ -1131,7 +1136,13 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
|
|||
|
||||
// Special check preventing `UnsafeCell` in the inner part of constants
|
||||
if self.ctfe_mode.is_some_and(|c| !c.allow_immutable_unsafe_cell()) {
|
||||
if !val.layout.is_zst()
|
||||
// Exclude ZST values. We need to compute the dynamic size/align to properly
|
||||
// handle slices and trait objects.
|
||||
let zst = self
|
||||
.ecx
|
||||
.size_and_align_of(&val.meta(), &val.layout)?
|
||||
.is_some_and(|(s, _a)| s.bytes() == 0);
|
||||
if !zst
|
||||
&& let Some(def) = val.layout.ty.ty_adt_def()
|
||||
&& def.is_unsafe_cell()
|
||||
{
|
||||
|
|
|
|||
15
tests/ui/consts/unsafe_cell_in_const.rs
Normal file
15
tests/ui/consts/unsafe_cell_in_const.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
//! Ensure we do not complain about zero-sized `UnsafeCell` in a const in any form.
|
||||
//! See <https://github.com/rust-lang/rust/issues/142948>.
|
||||
|
||||
//@ check-pass
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
const X1: &mut UnsafeCell<[i32; 0]> = UnsafeCell::from_mut(&mut []);
|
||||
|
||||
const X2: &mut UnsafeCell<[i32]> = UnsafeCell::from_mut(&mut []);
|
||||
|
||||
trait Trait {}
|
||||
impl Trait for [i32; 0] {}
|
||||
const X3: &mut UnsafeCell<dyn Trait> = UnsafeCell::from_mut(&mut []);
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue