Skip to content

Commit ffb6ba0

Browse files
committed
validation: better error when the enum discriminant is Undef
1 parent 4ec0ba9 commit ffb6ba0

File tree

9 files changed

+22
-20
lines changed

9 files changed

+22
-20
lines changed

src/librustc/mir/interpret/error.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ty::{Ty, layout};
1515
use ty::layout::{Size, Align, LayoutError};
1616
use rustc_target::spec::abi::Abi;
1717

18-
use super::{Pointer, Scalar};
18+
use super::{Pointer, ScalarMaybeUndef};
1919

2020
use backtrace::Backtrace;
2121

@@ -240,7 +240,7 @@ pub enum EvalErrorKind<'tcx, O> {
240240
InvalidMemoryAccess,
241241
InvalidFunctionPointer,
242242
InvalidBool,
243-
InvalidDiscriminant(Scalar),
243+
InvalidDiscriminant(ScalarMaybeUndef),
244244
PointerOutOfBounds {
245245
ptr: Pointer,
246246
access: bool,

src/librustc_mir/interpret/operand.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
601601
// read raw discriminant value
602602
let discr_op = self.operand_field(rval, 0)?;
603603
let discr_val = self.read_immediate(discr_op)?;
604-
let raw_discr = discr_val.to_scalar()?;
604+
let raw_discr = discr_val.to_scalar_or_undef();
605605
trace!("discr value: {:?}", raw_discr);
606606
// post-process
607607
Ok(match rval.layout.variants {
@@ -647,13 +647,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
647647
let variants_start = niche_variants.start().as_u32() as u128;
648648
let variants_end = niche_variants.end().as_u32() as u128;
649649
match raw_discr {
650-
Scalar::Ptr(_) => {
650+
ScalarMaybeUndef::Scalar(Scalar::Ptr(_)) => {
651651
// The niche must be just 0 (which a pointer value never is)
652652
assert!(niche_start == 0);
653653
assert!(variants_start == variants_end);
654654
(dataful_variant.as_u32() as u128, dataful_variant)
655655
},
656-
Scalar::Bits { bits: raw_discr, size } => {
656+
ScalarMaybeUndef::Scalar(Scalar::Bits { bits: raw_discr, size }) => {
657657
assert_eq!(size as u64, discr_val.layout.size.bytes());
658658
let discr = raw_discr.wrapping_sub(niche_start)
659659
.wrapping_add(variants_start);
@@ -669,6 +669,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
669669
(dataful_variant.as_u32() as u128, dataful_variant)
670670
}
671671
},
672+
ScalarMaybeUndef::Undef =>
673+
return err!(InvalidDiscriminant(ScalarMaybeUndef::Undef)),
672674
}
673675
}
674676
})

src/librustc_mir/interpret/validity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
274274
),
275275
EvalErrorKind::ReadPointerAsBytes =>
276276
validation_failure!(
277-
"a pointer", self.path, "plain bytes"
277+
"a pointer", self.path, "plain (non-pointer) bytes"
278278
),
279279
_ => Err(err),
280280
}
@@ -304,7 +304,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
304304
if self.const_mode {
305305
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
306306
try_validation!(value.to_bits(size),
307-
value, self.path, "initialized plain bits");
307+
value, self.path, "initialized plain (non-pointer) bytes");
308308
} else {
309309
// At run-time, for now, we accept *anything* for these types, including
310310
// undef. We should fix that, but let's start low.

src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/const-pointer-values-in-various-types.rs:24:5
33
|
44
LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

@@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
3636
--> $DIR/const-pointer-values-in-various-types.rs:36:5
3737
|
3838
LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
39-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
4040
|
4141
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4242

@@ -74,7 +74,7 @@ error[E0080]: it is undefined behavior to use this value
7474
--> $DIR/const-pointer-values-in-various-types.rs:51:5
7575
|
7676
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
7878
|
7979
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
8080

@@ -96,7 +96,7 @@ error[E0080]: it is undefined behavior to use this value
9696
--> $DIR/const-pointer-values-in-various-types.rs:60:5
9797
|
9898
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
99-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
99+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
100100
|
101101
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
102102

@@ -144,7 +144,7 @@ error[E0080]: it is undefined behavior to use this value
144144
--> $DIR/const-pointer-values-in-various-types.rs:78:5
145145
|
146146
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
147-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
147+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
148148
|
149149
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
150150

@@ -184,7 +184,7 @@ error[E0080]: it is undefined behavior to use this value
184184
--> $DIR/const-pointer-values-in-various-types.rs:93:5
185185
|
186186
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
187-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
187+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
188188
|
189189
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
190190

@@ -208,7 +208,7 @@ error[E0080]: it is undefined behavior to use this value
208208
--> $DIR/const-pointer-values-in-various-types.rs:102:5
209209
|
210210
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
211-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
211+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
212212
|
213213
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
214214

src/test/ui/consts/const-eval/issue-52442.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error[E0080]: it is undefined behavior to use this value
88
--> $DIR/issue-52442.rs:12:11
99
|
1010
LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
1212
|
1313
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
1414

src/test/ui/consts/const-eval/ref_to_int_match.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/ref_to_int_match.rs:33:1
33
|
44
LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; //~ ERROR it is undefined behavior to use this value
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

src/test/ui/consts/const-eval/ub-enum.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
3434
--> $DIR/ub-enum.rs:51:1
3535
|
3636
LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at [0], but expected a valid enum discriminant
3838
|
3939
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4040

src/test/ui/consts/const-eval/ub-ref.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ error[E0080]: it is undefined behavior to use this value
1818
--> $DIR/ub-ref.rs:22:1
1919
|
2020
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
2222
|
2323
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
2424

2525
error[E0080]: it is undefined behavior to use this value
2626
--> $DIR/ub-ref.rs:25:1
2727
|
2828
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain bytes
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
3030
|
3131
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
3232

src/test/ui/consts/const-eval/union-ice.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | / const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to
1313
LL | | a: 42,
1414
LL | | b: unsafe { UNION.field3 },
1515
LL | | };
16-
| |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain bits
16+
| |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes
1717
|
1818
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
1919

0 commit comments

Comments
 (0)