validation: better error when the enum discriminant is Undef
This commit is contained in:
parent
4ec0ba9545
commit
ffb6ba0828
@ -15,7 +15,7 @@
|
||||
use ty::layout::{Size, Align, LayoutError};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use super::{Pointer, Scalar};
|
||||
use super::{Pointer, ScalarMaybeUndef};
|
||||
|
||||
use backtrace::Backtrace;
|
||||
|
||||
@ -240,7 +240,7 @@ pub enum EvalErrorKind<'tcx, O> {
|
||||
InvalidMemoryAccess,
|
||||
InvalidFunctionPointer,
|
||||
InvalidBool,
|
||||
InvalidDiscriminant(Scalar),
|
||||
InvalidDiscriminant(ScalarMaybeUndef),
|
||||
PointerOutOfBounds {
|
||||
ptr: Pointer,
|
||||
access: bool,
|
||||
|
@ -601,7 +601,7 @@ pub fn read_discriminant(
|
||||
// read raw discriminant value
|
||||
let discr_op = self.operand_field(rval, 0)?;
|
||||
let discr_val = self.read_immediate(discr_op)?;
|
||||
let raw_discr = discr_val.to_scalar()?;
|
||||
let raw_discr = discr_val.to_scalar_or_undef();
|
||||
trace!("discr value: {:?}", raw_discr);
|
||||
// post-process
|
||||
Ok(match rval.layout.variants {
|
||||
@ -647,13 +647,13 @@ pub fn read_discriminant(
|
||||
let variants_start = niche_variants.start().as_u32() as u128;
|
||||
let variants_end = niche_variants.end().as_u32() as u128;
|
||||
match raw_discr {
|
||||
Scalar::Ptr(_) => {
|
||||
ScalarMaybeUndef::Scalar(Scalar::Ptr(_)) => {
|
||||
// The niche must be just 0 (which a pointer value never is)
|
||||
assert!(niche_start == 0);
|
||||
assert!(variants_start == variants_end);
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
},
|
||||
Scalar::Bits { bits: raw_discr, size } => {
|
||||
ScalarMaybeUndef::Scalar(Scalar::Bits { bits: raw_discr, size }) => {
|
||||
assert_eq!(size as u64, discr_val.layout.size.bytes());
|
||||
let discr = raw_discr.wrapping_sub(niche_start)
|
||||
.wrapping_add(variants_start);
|
||||
@ -669,6 +669,8 @@ pub fn read_discriminant(
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
}
|
||||
},
|
||||
ScalarMaybeUndef::Undef =>
|
||||
return err!(InvalidDiscriminant(ScalarMaybeUndef::Undef)),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -274,7 +274,7 @@ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
|
||||
),
|
||||
EvalErrorKind::ReadPointerAsBytes =>
|
||||
validation_failure!(
|
||||
"a pointer", self.path, "plain bytes"
|
||||
"a pointer", self.path, "plain (non-pointer) bytes"
|
||||
),
|
||||
_ => Err(err),
|
||||
}
|
||||
@ -304,7 +304,7 @@ fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'
|
||||
if self.const_mode {
|
||||
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
|
||||
try_validation!(value.to_bits(size),
|
||||
value, self.path, "initialized plain bits");
|
||||
value, self.path, "initialized plain (non-pointer) bytes");
|
||||
} else {
|
||||
// At run-time, for now, we accept *anything* for these types, including
|
||||
// undef. We should fix that, but let's start low.
|
||||
|
@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:24:5
|
||||
|
|
||||
LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:36:5
|
||||
|
|
||||
LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -74,7 +74,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:51:5
|
||||
|
|
||||
LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -96,7 +96,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:60:5
|
||||
|
|
||||
LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -144,7 +144,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:78:5
|
||||
|
|
||||
LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -184,7 +184,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:93:5
|
||||
|
|
||||
LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -208,7 +208,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/const-pointer-values-in-various-types.rs:102:5
|
||||
|
|
||||
LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
|
@ -8,7 +8,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/issue-52442.rs:12:11
|
||||
|
|
||||
LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ref_to_int_match.rs:33:1
|
||||
|
|
||||
LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; //~ ERROR it is undefined behavior to use this value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
|
@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-enum.rs:51:1
|
||||
|
|
||||
LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at [0], but expected a valid enum discriminant
|
||||
|
|
||||
= 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
|
||||
|
||||
|
@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref.rs:22:1
|
||||
|
|
||||
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-ref.rs:25:1
|
||||
|
|
||||
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain bytes
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
|
@ -13,7 +13,7 @@ LL | / const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to
|
||||
LL | | a: 42,
|
||||
LL | | b: unsafe { UNION.field3 },
|
||||
LL | | };
|
||||
| |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain bits
|
||||
| |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes
|
||||
|
|
||||
= 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user