Skip to content

Commit b836329

Browse files
committed
Auto merge of #71274 - RalfJung:raw-init-check-aggregate, r=petrochenkov
might_permit_raw_init: also check aggregate fields This is the next step for #66151: when doing `mem::zeroed`/`mem::uninitialized`, also recursively check fields of aggregates (except for arrays) for whether they permit zero/uninit initialization.
2 parents 71bdb84 + 3009c52 commit b836329

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

compiler/rustc_target/src/abi/mod.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -1135,16 +1135,31 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
11351135
Abi::Scalar(s) => scalar_allows_raw_init(s),
11361136
Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
11371137
Abi::Vector { element: s, count } => *count == 0 || scalar_allows_raw_init(s),
1138-
Abi::Aggregate { .. } => true, // Cannot be excluded *right now*.
1138+
Abi::Aggregate { .. } => true, // Fields are checked below.
11391139
};
11401140
if !valid {
11411141
// This is definitely not okay.
1142-
trace!("might_permit_raw_init({:?}, zero={}): not valid", self.layout, zero);
11431142
return Ok(false);
11441143
}
11451144

1146-
// If we have not found an error yet, we need to recursively descend.
1147-
// FIXME(#66151): For now, we are conservative and do not do this.
1145+
// If we have not found an error yet, we need to recursively descend into fields.
1146+
match &self.fields {
1147+
FieldsShape::Primitive | FieldsShape::Union { .. } => {}
1148+
FieldsShape::Array { .. } => {
1149+
// FIXME(#66151): For now, we are conservative and do not check arrays.
1150+
}
1151+
FieldsShape::Arbitrary { offsets, .. } => {
1152+
for idx in 0..offsets.len() {
1153+
let field = self.field(cx, idx).to_result()?;
1154+
if !field.might_permit_raw_init(cx, zero)? {
1155+
// We found a field that is unhappy with this kind of initialization.
1156+
return Ok(false);
1157+
}
1158+
}
1159+
}
1160+
}
1161+
1162+
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
11481163
Ok(true)
11491164
}
11501165
}

src/test/ui/intrinsics/panic-uninitialized-zeroed.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
55

6-
#![feature(never_type)]
6+
#![feature(never_type, arbitrary_enum_discriminant)]
77
#![allow(deprecated, invalid_value)]
88

99
use std::{
@@ -24,6 +24,20 @@ enum Bar {}
2424
#[allow(dead_code)]
2525
enum OneVariant { Variant(i32) }
2626

27+
#[allow(dead_code, non_camel_case_types)]
28+
enum OneVariant_NonZero {
29+
Variant(i32, i32, num::NonZeroI32),
30+
DeadVariant(Bar),
31+
}
32+
33+
// An `Aggregate` abi enum where 0 is not a valid discriminant.
34+
#[allow(dead_code)]
35+
#[repr(i32)]
36+
enum NoNullVariant {
37+
Variant1(i32, i32) = 1,
38+
Variant2(i32, i32) = 2,
39+
}
40+
2741
// An enum with ScalarPair layout
2842
#[allow(dead_code)]
2943
enum LR {
@@ -125,6 +139,7 @@ fn main() {
125139
"attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
126140
which is invalid"
127141
);
142+
*/
128143

129144
test_panic_msg(
130145
|| mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
@@ -136,7 +151,28 @@ fn main() {
136151
"attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
137152
which is invalid"
138153
);
139-
*/
154+
155+
test_panic_msg(
156+
|| mem::uninitialized::<OneVariant_NonZero>(),
157+
"attempted to leave type `OneVariant_NonZero` uninitialized, \
158+
which is invalid"
159+
);
160+
test_panic_msg(
161+
|| mem::zeroed::<OneVariant_NonZero>(),
162+
"attempted to zero-initialize type `OneVariant_NonZero`, \
163+
which is invalid"
164+
);
165+
166+
test_panic_msg(
167+
|| mem::uninitialized::<NoNullVariant>(),
168+
"attempted to leave type `NoNullVariant` uninitialized, \
169+
which is invalid"
170+
);
171+
test_panic_msg(
172+
|| mem::zeroed::<NoNullVariant>(),
173+
"attempted to zero-initialize type `NoNullVariant`, \
174+
which is invalid"
175+
);
140176

141177
// Types that can be zero, but not uninit.
142178
test_panic_msg(

src/tools/cargotest/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ const TEST_REPOS: &[Test] = &[
2222
Test {
2323
name: "ripgrep",
2424
repo: "https://github.com/BurntSushi/ripgrep",
25-
sha: "ad9befbc1d3b5c695e7f6b6734ee1b8e683edd41",
25+
sha: "3de31f752729525d85a3d1575ac1978733b3f7e7",
2626
lock: None,
2727
packages: &[],
2828
},
2929
Test {
3030
name: "tokei",
3131
repo: "https://github.com/XAMPPRocky/tokei",
32-
sha: "a950ff128d5a435a8083b1c7577c0431f98360ca",
32+
sha: "fdf3f8cb279a7aeac0696c87e5d8b0cd946e4f9e",
3333
lock: None,
3434
packages: &[],
3535
},

0 commit comments

Comments
 (0)