Skip to content

Commit aa1435b

Browse files
committed
const validation ub tests: use transmute instead of unions
1 parent d47196b commit aa1435b

File tree

8 files changed

+165
-221
lines changed

8 files changed

+165
-221
lines changed

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

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#![feature(const_transmute)]
12
#![allow(const_err)] // make sure we cannot allow away the errors tested here
23

4+
use std::mem;
35

46
#[repr(transparent)]
57
#[derive(Copy, Clone)]
@@ -10,23 +12,16 @@ struct Wrap<T>(T);
1012
enum Enum {
1113
A = 0,
1214
}
13-
#[repr(C)]
14-
union TransmuteEnum {
15-
in1: &'static u8,
16-
in2: usize,
17-
out1: Enum,
18-
out2: Wrap<Enum>,
19-
}
2015

21-
const GOOD_ENUM: Enum = unsafe { TransmuteEnum { in2: 0 }.out1 };
16+
const GOOD_ENUM: Enum = unsafe { mem::transmute(0usize) };
2217

23-
const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
18+
const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
2419
//~^ ERROR is undefined behavior
2520

26-
const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
21+
const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
2722
//~^ ERROR is undefined behavior
2823

29-
const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
24+
const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
3025
//~^ ERROR is undefined behavior
3126

3227
// (Potentially) invalid enum discriminant
@@ -36,39 +31,31 @@ enum Enum2 {
3631
A = 2,
3732
}
3833

39-
#[repr(C)]
40-
union TransmuteEnum2 {
41-
in1: usize,
42-
in2: &'static u8,
43-
in3: (),
44-
out1: Enum2,
45-
out2: Wrap<Enum2>, // something wrapping the enum so that we test layout first, not enum
46-
out3: Option<Enum2>,
47-
}
48-
const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
34+
const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
4935
//~^ ERROR is undefined behavior
50-
const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
36+
const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
5137
//~^ ERROR is undefined behavior
52-
const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
38+
// something wrapping the enum so that we test layout first, not enum
39+
const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
5340
//~^ ERROR is undefined behavior
5441

5542
// Undef enum discriminant.
56-
const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
43+
#[repr(C)]
44+
union MaybeUninit<T: Copy> {
45+
uninit: (),
46+
init: T,
47+
}
48+
const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
5749
//~^ ERROR is undefined behavior
5850

5951
// Pointer value in an enum with a niche that is not just 0.
60-
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
52+
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
6153
//~^ ERROR is undefined behavior
6254

6355
// Invalid enum field content (mostly to test printing of paths for enum tuple
6456
// variants and tuples).
65-
#[repr(C)]
66-
union TransmuteChar {
67-
a: u32,
68-
b: char,
69-
}
7057
// Need to create something which does not clash with enum layout optimizations.
71-
const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
58+
const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
7259
//~^ ERROR is undefined behavior
7360

7461
fn main() {

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

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,72 @@
11
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/ub-enum.rs:23:1
2+
--> $DIR/ub-enum.rs:18:1
33
|
4-
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
4+
LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
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 rustc repository if you believe it should not be considered undefined behavior.
88

99
error[E0080]: it is undefined behavior to use this value
10-
--> $DIR/ub-enum.rs:26:1
10+
--> $DIR/ub-enum.rs:21:1
1111
|
12-
LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
12+
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
1414
|
1515
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
1616

1717
error[E0080]: it is undefined behavior to use this value
18-
--> $DIR/ub-enum.rs:29:1
18+
--> $DIR/ub-enum.rs:24:1
1919
|
20-
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
20+
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .0.<enum-tag>, 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 rustc repository if you believe it should not be considered undefined behavior.
2424

2525
error[E0080]: it is undefined behavior to use this value
26-
--> $DIR/ub-enum.rs:48:1
26+
--> $DIR/ub-enum.rs:34:1
2727
|
28-
LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
28+
LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
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 rustc repository if you believe it should not be considered undefined behavior.
3232

3333
error[E0080]: it is undefined behavior to use this value
34-
--> $DIR/ub-enum.rs:50:1
34+
--> $DIR/ub-enum.rs:36:1
3535
|
36-
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
36+
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
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 rustc repository if you believe it should not be considered undefined behavior.
4040

4141
error[E0080]: it is undefined behavior to use this value
42-
--> $DIR/ub-enum.rs:52:1
42+
--> $DIR/ub-enum.rs:39:1
4343
|
44-
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
44+
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
4646
|
4747
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
4848

4949
error[E0080]: it is undefined behavior to use this value
50-
--> $DIR/ub-enum.rs:56:1
50+
--> $DIR/ub-enum.rs:48:1
5151
|
52-
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
52+
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
5353
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .<enum-tag>, but expected initialized plain (non-pointer) bytes
5454
|
5555
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
5656

5757
error[E0080]: it is undefined behavior to use this value
58-
--> $DIR/ub-enum.rs:60:1
58+
--> $DIR/ub-enum.rs:52:1
5959
|
60-
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
60+
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<enum-tag>, but expected initialized plain (non-pointer) bytes
6262
|
6363
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
6464

6565
error[E0080]: it is undefined behavior to use this value
66-
--> $DIR/ub-enum.rs:71:1
66+
--> $DIR/ub-enum.rs:58:1
6767
|
68-
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
69-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<enum-variant(Some)>.0.1, but expected a valid unicode codepoint
68+
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
69+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<enum-variant(Some)>.0.1, but expected a valid unicode codepoint
7070
|
7171
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
7272

src/test/ui/consts/const-eval/ub-nonnull.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
2525
//~^ ERROR it is undefined behavior to use this value
2626

2727
#[repr(C)]
28-
union Transmute {
28+
union MaybeUninit<T: Copy> {
2929
uninit: (),
30-
out: NonZeroU8,
30+
init: T,
3131
}
32-
const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
32+
const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
3333
//~^ ERROR it is undefined behavior to use this value
3434

3535
// Also test other uses of rustc_layout_scalar_valid_range_start

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
4343
error[E0080]: it is undefined behavior to use this value
4444
--> $DIR/ub-nonnull.rs:32:1
4545
|
46-
LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
47-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .0, but expected initialized plain (non-pointer) bytes
46+
LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .0, but expected initialized plain (non-pointer) bytes
4848
|
4949
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
5050

src/test/ui/consts/const-eval/ub-uninhabit.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ use std::mem;
77
enum Bar {}
88

99
#[repr(C)]
10-
union TransmuteUnion<A: Clone + Copy, B: Clone + Copy> {
11-
a: A,
12-
b: B,
10+
union MaybeUninit<T: Copy> {
11+
uninit: (),
12+
init: T,
1313
}
1414

15-
const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b };
15+
const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
1616
//~^ ERROR it is undefined behavior to use this value
1717

1818
const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
1919
//~^ ERROR it is undefined behavior to use this value
2020

21-
const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b };
21+
const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
2222
//~^ ERROR it is undefined behavior to use this value
2323

2424
fn main() {}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0080]: it is undefined behavior to use this value
22
--> $DIR/ub-uninhabit.rs:15:1
33
|
4-
LL | const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar
4+
LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar
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 rustc repository if you believe it should not be considered undefined behavior.
88

@@ -17,8 +17,8 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
1717
error[E0080]: it is undefined behavior to use this value
1818
--> $DIR/ub-uninhabit.rs:21:1
1919
|
20-
LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b };
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at [0]
20+
LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Bar at [0]
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 rustc repository if you believe it should not be considered undefined behavior.
2424

0 commit comments

Comments
 (0)