]>
Commit | Line | Data |
---|---|---|
a2a8927a XL |
1 | // Check that constants with interior mutability inside unions are rejected |
2 | // during validation. | |
3 | // | |
4 | // Note that this test case relies on undefined behaviour to construct a | |
5 | // constant with interior mutability that is "invisible" to the static checks. | |
6 | // If for some reason this approach no longer works, it is should be fine to | |
7 | // remove the test case. | |
8 | // | |
9 | // build-fail | |
10 | // stderr-per-bitwidth | |
11 | #![feature(const_mut_refs)] | |
a2a8927a XL |
12 | #![feature(untagged_unions)] |
13 | use std::cell::Cell; | |
14 | ||
15 | #[repr(C)] | |
16 | struct S { | |
17 | x: u32, | |
18 | y: E, | |
19 | } | |
20 | ||
21 | #[repr(u32)] | |
22 | enum E { | |
23 | A, | |
24 | B(U) | |
25 | } | |
26 | ||
27 | union U { | |
28 | cell: Cell<u32>, | |
29 | } | |
30 | ||
31 | const C: S = { | |
32 | let s = S { x: 0, y: E::A }; | |
33 | // Go through an &u32 reference which is definitely not allowed to mutate anything. | |
34 | let p = &s.x as *const u32 as *mut u32; | |
35 | // Change enum tag to E::B. | |
36 | unsafe { *p.add(1) = 1 }; | |
37 | s | |
38 | }; | |
39 | ||
40 | fn main() { //~ ERROR it is undefined behavior to use this value | |
41 | let _: &'static _ = &C; //~ ERROR erroneous constant used | |
42 | //~^ WARN this was previously accepted | |
43 | } |