summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-27 10:17:09 +0000
committerbors <bors@rust-lang.org>2020-09-27 10:17:09 +0000
commitb8363295d555494bbaa119eba8b16a3057e6728c (patch)
treed9e3c3424324d78e289909f578c7d0fd0ff703e8
parentAuto merge of #76955 - jyn514:refactor-diagnostics, r=euclio (diff)
parentupdate tokei and ripgrep in cargotest (diff)
downloadrust-b8363295d555494bbaa119eba8b16a3057e6728c.tar.gz
rust-b8363295d555494bbaa119eba8b16a3057e6728c.tar.bz2
rust-b8363295d555494bbaa119eba8b16a3057e6728c.tar.xz
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 https://github.com/rust-lang/rust/issues/66151: when doing `mem::zeroed`/`mem::uninitialized`, also recursively check fields of aggregates (except for arrays) for whether they permit zero/uninit initialization.
-rw-r--r--compiler/rustc_target/src/abi/mod.rs23
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs40
-rw-r--r--src/tools/cargotest/main.rs4
3 files changed, 59 insertions, 8 deletions
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 4b565dd..3c1a2ea 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -1135,16 +1135,31 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
1135 Abi::Scalar(s) => scalar_allows_raw_init(s), 1135 Abi::Scalar(s) => scalar_allows_raw_init(s),
1136 Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), 1136 Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
1137 Abi::Vector { element: s, count } => *count == 0 || scalar_allows_raw_init(s), 1137 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.
1139 }; 1139 };
1140 if !valid { 1140 if !valid {
1141 // This is definitely not okay. 1141 // This is definitely not okay.
1142 trace!("might_permit_raw_init({:?}, zero={}): not valid", self.layout, zero);
1143 return Ok(false); 1142 return Ok(false);
1144 } 1143 }
1145 1144
1146 // If we have not found an error yet, we need to recursively descend. 1145 // If we have not found an error yet, we need to recursively descend into fields.
1147 // FIXME(#66151): For now, we are conservative and do not do this. 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`.
1148 Ok(true) 1163 Ok(true)
1149 } 1164 }
1150} 1165}
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index 02f8eca..24474ca 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -3,7 +3,7 @@
3 3
4// This test checks panic emitted from `mem::{uninitialized,zeroed}`. 4// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
5 5
6#![feature(never_type)] 6#![feature(never_type, arbitrary_enum_discriminant)]
7#![allow(deprecated, invalid_value)] 7#![allow(deprecated, invalid_value)]
8 8
9use std::{ 9use std::{
@@ -24,6 +24,20 @@ enum Bar {}
24#[allow(dead_code)] 24#[allow(dead_code)]
25enum OneVariant { Variant(i32) } 25enum OneVariant { Variant(i32) }
26 26
27#[allow(dead_code, non_camel_case_types)]
28enum 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)]
36enum NoNullVariant {
37 Variant1(i32, i32) = 1,
38 Variant2(i32, i32) = 2,
39}
40
27// An enum with ScalarPair layout 41// An enum with ScalarPair layout
28#[allow(dead_code)] 42#[allow(dead_code)]
29enum LR { 43enum LR {
@@ -125,6 +139,7 @@ fn main() {
125 "attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \ 139 "attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
126 which is invalid" 140 which is invalid"
127 ); 141 );
142 */
128 143
129 test_panic_msg( 144 test_panic_msg(
130 || mem::uninitialized::<(NonNull<u32>, u32, u32)>(), 145 || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
@@ -136,7 +151,28 @@ fn main() {
136 "attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \ 151 "attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
137 which is invalid" 152 which is invalid"
138 ); 153 );
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 );
140 176
141 // Types that can be zero, but not uninit. 177 // Types that can be zero, but not uninit.
142 test_panic_msg( 178 test_panic_msg(
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index b65163a..8aabe07 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -22,14 +22,14 @@ const TEST_REPOS: &[Test] = &[
22 Test { 22 Test {
23 name: "ripgrep", 23 name: "ripgrep",
24 repo: "https://github.com/BurntSushi/ripgrep", 24 repo: "https://github.com/BurntSushi/ripgrep",
25 sha: "ad9befbc1d3b5c695e7f6b6734ee1b8e683edd41", 25 sha: "3de31f752729525d85a3d1575ac1978733b3f7e7",
26 lock: None, 26 lock: None,
27 packages: &[], 27 packages: &[],
28 }, 28 },
29 Test { 29 Test {
30 name: "tokei", 30 name: "tokei",
31 repo: "https://github.com/XAMPPRocky/tokei", 31 repo: "https://github.com/XAMPPRocky/tokei",
32 sha: "a950ff128d5a435a8083b1c7577c0431f98360ca", 32 sha: "fdf3f8cb279a7aeac0696c87e5d8b0cd946e4f9e",
33 lock: None, 33 lock: None,
34 packages: &[], 34 packages: &[],
35 }, 35 },