From b12151c40d8ad3f1d4c45bd8bd2da9cc94076d5a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Feb 2024 15:26:55 +0100 Subject: [PATCH] interpret/write_discriminant: when encoding niched variant, ensure the stored value matches --- ...um-set-discriminant-niche-variant-wrong.rs | 31 +++++++++++++++++++ ...et-discriminant-niche-variant-wrong.stderr | 20 ++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/fail/enum-set-discriminant-niche-variant-wrong.rs create mode 100644 tests/fail/enum-set-discriminant-niche-variant-wrong.stderr diff --git a/tests/fail/enum-set-discriminant-niche-variant-wrong.rs b/tests/fail/enum-set-discriminant-niche-variant-wrong.rs new file mode 100644 index 0000000000..7097aa0c43 --- /dev/null +++ b/tests/fail/enum-set-discriminant-niche-variant-wrong.rs @@ -0,0 +1,31 @@ +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; +use std::num::NonZeroI32; + +// We define our own option type so that we can control the varian indices. +#[allow(unused)] +enum Option { + None, + Some(T), +} +use Option::*; + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn set_discriminant(ptr: &mut Option) { + mir! { + { + // We set the discriminant to `Some`, which is a NOP since this is the niched variant. + // However, the enum is actually encoding `None` currently! That's not good... + SetDiscriminant(*ptr, 1); + //~^ ERROR: trying to set discriminant of a Option> to the niched variant, but the value does not match + Return() + } + } +} + +pub fn main() { + let mut v = None; + set_discriminant(&mut v); +} diff --git a/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr b/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr new file mode 100644 index 0000000000..a48a0a993d --- /dev/null +++ b/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: trying to set discriminant of a Option> to the niched variant, but the value does not match + --> $DIR/enum-set-discriminant-niche-variant-wrong.rs:LL:CC + | +LL | SetDiscriminant(*ptr, 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ trying to set discriminant of a Option> to the niched variant, but the value does not match + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `set_discriminant` at $DIR/enum-set-discriminant-niche-variant-wrong.rs:LL:CC +note: inside `main` + --> $DIR/enum-set-discriminant-niche-variant-wrong.rs:LL:CC + | +LL | set_discriminant(&mut v); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error +