mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
might_permit_raw_init: also check aggregate fields
This commit is contained in:
parent
e599b53e67
commit
6f881b3b7d
@ -1135,16 +1135,31 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||||||
Abi::Scalar(s) => scalar_allows_raw_init(s),
|
Abi::Scalar(s) => scalar_allows_raw_init(s),
|
||||||
Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
|
Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
|
||||||
Abi::Vector { element: s, count } => *count == 0 || scalar_allows_raw_init(s),
|
Abi::Vector { element: s, count } => *count == 0 || scalar_allows_raw_init(s),
|
||||||
Abi::Aggregate { .. } => true, // Cannot be excluded *right now*.
|
Abi::Aggregate { .. } => true, // Fields are checked below.
|
||||||
};
|
};
|
||||||
if !valid {
|
if !valid {
|
||||||
// This is definitely not okay.
|
// This is definitely not okay.
|
||||||
trace!("might_permit_raw_init({:?}, zero={}): not valid", self.layout, zero);
|
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have not found an error yet, we need to recursively descend.
|
// If we have not found an error yet, we need to recursively descend into fields.
|
||||||
// FIXME(#66151): For now, we are conservative and do not do this.
|
match &self.fields {
|
||||||
|
FieldsShape::Primitive | FieldsShape::Union { .. } => {}
|
||||||
|
FieldsShape::Array { .. } => {
|
||||||
|
// FIXME(#66151): For now, we are conservative and do not check arrays.
|
||||||
|
}
|
||||||
|
FieldsShape::Arbitrary { offsets, .. } => {
|
||||||
|
for idx in 0..offsets.len() {
|
||||||
|
let field = self.field(cx, idx).to_result()?;
|
||||||
|
if !field.might_permit_raw_init(cx, zero)? {
|
||||||
|
// We found a field that is unhappy with this kind of initialization.
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
|
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
|
||||||
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type, arbitrary_enum_discriminant)]
|
||||||
#![allow(deprecated, invalid_value)]
|
#![allow(deprecated, invalid_value)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@ -24,6 +24,20 @@ enum Bar {}
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum OneVariant { Variant(i32) }
|
enum OneVariant { Variant(i32) }
|
||||||
|
|
||||||
|
#[allow(dead_code, non_camel_case_types)]
|
||||||
|
enum OneVariant_NonZero {
|
||||||
|
Variant(i32, i32, num::NonZeroI32),
|
||||||
|
DeadVariant(Bar),
|
||||||
|
}
|
||||||
|
|
||||||
|
// An `Aggregate` abi enum where 0 is not a valid discriminant.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[repr(i32)]
|
||||||
|
enum NoNullVariant {
|
||||||
|
Variant1(i32, i32) = 1,
|
||||||
|
Variant2(i32, i32) = 2,
|
||||||
|
}
|
||||||
|
|
||||||
// An enum with ScalarPair layout
|
// An enum with ScalarPair layout
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum LR {
|
enum LR {
|
||||||
@ -125,6 +139,7 @@ fn main() {
|
|||||||
"attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
|
"attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
|
||||||
which is invalid"
|
which is invalid"
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
test_panic_msg(
|
test_panic_msg(
|
||||||
|| mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
|
|| mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
|
||||||
@ -136,7 +151,28 @@ fn main() {
|
|||||||
"attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
|
"attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
|
||||||
which is invalid"
|
which is invalid"
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
|
test_panic_msg(
|
||||||
|
|| mem::uninitialized::<OneVariant_NonZero>(),
|
||||||
|
"attempted to leave type `OneVariant_NonZero` uninitialized, \
|
||||||
|
which is invalid"
|
||||||
|
);
|
||||||
|
test_panic_msg(
|
||||||
|
|| mem::zeroed::<OneVariant_NonZero>(),
|
||||||
|
"attempted to zero-initialize type `OneVariant_NonZero`, \
|
||||||
|
which is invalid"
|
||||||
|
);
|
||||||
|
|
||||||
|
test_panic_msg(
|
||||||
|
|| mem::uninitialized::<NoNullVariant>(),
|
||||||
|
"attempted to leave type `NoNullVariant` uninitialized, \
|
||||||
|
which is invalid"
|
||||||
|
);
|
||||||
|
test_panic_msg(
|
||||||
|
|| mem::zeroed::<NoNullVariant>(),
|
||||||
|
"attempted to zero-initialize type `NoNullVariant`, \
|
||||||
|
which is invalid"
|
||||||
|
);
|
||||||
|
|
||||||
// Types that can be zero, but not uninit.
|
// Types that can be zero, but not uninit.
|
||||||
test_panic_msg(
|
test_panic_msg(
|
||||||
|
Loading…
Reference in New Issue
Block a user