Skip to content

Commit f81549c

Browse files
Normalize struct tail properly in disalignment check
1 parent d9dd550 commit f81549c

File tree

4 files changed

+172
-15
lines changed

4 files changed

+172
-15
lines changed

Diff for: compiler/rustc_const_eval/src/util/alignment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ where
2222
};
2323

2424
let ty = place.ty(local_decls, tcx).ty;
25-
let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
25+
let unsized_tail = || tcx.struct_tail_erasing_lifetimes(ty, param_env);
2626
match tcx.layout_of(param_env.and(ty)) {
2727
Ok(layout)
2828
if layout.align.abi <= pack

Diff for: tests/ui/lint/unaligned_references.stderr renamed to tests/ui/lint/unaligned_references.current.stderr

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0793]: reference to packed field is unaligned
2-
--> $DIR/unaligned_references.rs:28:13
2+
--> $DIR/unaligned_references.rs:32:13
33
|
44
LL | &self.x;
55
| ^^^^^^^
@@ -9,7 +9,7 @@ LL | &self.x;
99
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
1010

1111
error[E0793]: reference to packed field is unaligned
12-
--> $DIR/unaligned_references.rs:40:24
12+
--> $DIR/unaligned_references.rs:44:24
1313
|
1414
LL | println!("{:?}", &*foo.0);
1515
| ^^^^^
@@ -19,7 +19,7 @@ LL | println!("{:?}", &*foo.0);
1919
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
2020

2121
error[E0793]: reference to packed field is unaligned
22-
--> $DIR/unaligned_references.rs:42:24
22+
--> $DIR/unaligned_references.rs:46:24
2323
|
2424
LL | println!("{:?}", &*foo.0);
2525
| ^^^^^
@@ -29,7 +29,7 @@ LL | println!("{:?}", &*foo.0);
2929
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
3030

3131
error[E0793]: reference to packed field is unaligned
32-
--> $DIR/unaligned_references.rs:47:24
32+
--> $DIR/unaligned_references.rs:51:24
3333
|
3434
LL | println!("{:?}", &*foo.0);
3535
| ^^^^^
@@ -39,7 +39,7 @@ LL | println!("{:?}", &*foo.0);
3939
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
4040

4141
error[E0793]: reference to packed field is unaligned
42-
--> $DIR/unaligned_references.rs:57:17
42+
--> $DIR/unaligned_references.rs:81:17
4343
|
4444
LL | let _ = &good.ptr;
4545
| ^^^^^^^^^
@@ -49,7 +49,7 @@ LL | let _ = &good.ptr;
4949
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
5050

5151
error[E0793]: reference to packed field is unaligned
52-
--> $DIR/unaligned_references.rs:58:17
52+
--> $DIR/unaligned_references.rs:82:17
5353
|
5454
LL | let _ = &good.data;
5555
| ^^^^^^^^^^
@@ -59,7 +59,7 @@ LL | let _ = &good.data;
5959
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
6060

6161
error[E0793]: reference to packed field is unaligned
62-
--> $DIR/unaligned_references.rs:60:17
62+
--> $DIR/unaligned_references.rs:84:17
6363
|
6464
LL | let _ = &good.data as *const _;
6565
| ^^^^^^^^^^
@@ -69,7 +69,7 @@ LL | let _ = &good.data as *const _;
6969
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
7070

7171
error[E0793]: reference to packed field is unaligned
72-
--> $DIR/unaligned_references.rs:61:27
72+
--> $DIR/unaligned_references.rs:85:27
7373
|
7474
LL | let _: *const _ = &good.data;
7575
| ^^^^^^^^^^
@@ -79,7 +79,7 @@ LL | let _: *const _ = &good.data;
7979
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
8080

8181
error[E0793]: reference to packed field is unaligned
82-
--> $DIR/unaligned_references.rs:63:17
82+
--> $DIR/unaligned_references.rs:87:17
8383
|
8484
LL | let _ = good.data.clone();
8585
| ^^^^^^^^^
@@ -89,7 +89,7 @@ LL | let _ = good.data.clone();
8989
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
9090

9191
error[E0793]: reference to packed field is unaligned
92-
--> $DIR/unaligned_references.rs:65:17
92+
--> $DIR/unaligned_references.rs:89:17
9393
|
9494
LL | let _ = &good.data2[0];
9595
| ^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | let _ = &good.data2[0];
9999
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
100100

101101
error[E0793]: reference to packed field is unaligned
102-
--> $DIR/unaligned_references.rs:74:17
102+
--> $DIR/unaligned_references.rs:98:17
103103
|
104104
LL | let _ = &packed2.x;
105105
| ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL | let _ = &packed2.x;
109109
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
110110

111111
error[E0793]: reference to packed field is unaligned
112-
--> $DIR/unaligned_references.rs:113:20
112+
--> $DIR/unaligned_references.rs:137:20
113113
|
114114
LL | let _ref = &m1.1.a;
115115
| ^^^^^^^
@@ -119,7 +119,7 @@ LL | let _ref = &m1.1.a;
119119
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
120120

121121
error[E0793]: reference to packed field is unaligned
122-
--> $DIR/unaligned_references.rs:116:20
122+
--> $DIR/unaligned_references.rs:140:20
123123
|
124124
LL | let _ref = &m2.1.a;
125125
| ^^^^^^^

Diff for: tests/ui/lint/unaligned_references.next.stderr

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
error[E0793]: reference to packed field is unaligned
2+
--> $DIR/unaligned_references.rs:32:13
3+
|
4+
LL | &self.x;
5+
| ^^^^^^^
6+
|
7+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
8+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
9+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
10+
11+
error[E0793]: reference to packed field is unaligned
12+
--> $DIR/unaligned_references.rs:44:24
13+
|
14+
LL | println!("{:?}", &*foo.0);
15+
| ^^^^^
16+
|
17+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
18+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
19+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
20+
21+
error[E0793]: reference to packed field is unaligned
22+
--> $DIR/unaligned_references.rs:46:24
23+
|
24+
LL | println!("{:?}", &*foo.0);
25+
| ^^^^^
26+
|
27+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
28+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
29+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
30+
31+
error[E0793]: reference to packed field is unaligned
32+
--> $DIR/unaligned_references.rs:51:24
33+
|
34+
LL | println!("{:?}", &*foo.0);
35+
| ^^^^^
36+
|
37+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
38+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
39+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
40+
41+
error[E0793]: reference to packed field is unaligned
42+
--> $DIR/unaligned_references.rs:81:17
43+
|
44+
LL | let _ = &good.ptr;
45+
| ^^^^^^^^^
46+
|
47+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
48+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
49+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
50+
51+
error[E0793]: reference to packed field is unaligned
52+
--> $DIR/unaligned_references.rs:82:17
53+
|
54+
LL | let _ = &good.data;
55+
| ^^^^^^^^^^
56+
|
57+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
58+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
59+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
60+
61+
error[E0793]: reference to packed field is unaligned
62+
--> $DIR/unaligned_references.rs:84:17
63+
|
64+
LL | let _ = &good.data as *const _;
65+
| ^^^^^^^^^^
66+
|
67+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
68+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
69+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
70+
71+
error[E0793]: reference to packed field is unaligned
72+
--> $DIR/unaligned_references.rs:85:27
73+
|
74+
LL | let _: *const _ = &good.data;
75+
| ^^^^^^^^^^
76+
|
77+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
78+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
79+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
80+
81+
error[E0793]: reference to packed field is unaligned
82+
--> $DIR/unaligned_references.rs:87:17
83+
|
84+
LL | let _ = good.data.clone();
85+
| ^^^^^^^^^
86+
|
87+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
88+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
89+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
90+
91+
error[E0793]: reference to packed field is unaligned
92+
--> $DIR/unaligned_references.rs:89:17
93+
|
94+
LL | let _ = &good.data2[0];
95+
| ^^^^^^^^^^^^^^
96+
|
97+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
98+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
99+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
100+
101+
error[E0793]: reference to packed field is unaligned
102+
--> $DIR/unaligned_references.rs:98:17
103+
|
104+
LL | let _ = &packed2.x;
105+
| ^^^^^^^^^^
106+
|
107+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
108+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
109+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
110+
111+
error[E0793]: reference to packed field is unaligned
112+
--> $DIR/unaligned_references.rs:137:20
113+
|
114+
LL | let _ref = &m1.1.a;
115+
| ^^^^^^^
116+
|
117+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
118+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
119+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
120+
121+
error[E0793]: reference to packed field is unaligned
122+
--> $DIR/unaligned_references.rs:140:20
123+
|
124+
LL | let _ref = &m2.1.a;
125+
| ^^^^^^^
126+
|
127+
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
128+
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
129+
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
130+
131+
error: aborting due to 13 previous errors
132+
133+
For more information about this error, try `rustc --explain E0793`.

Diff for: tests/ui/lint/unaligned_references.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
use std::mem::ManuallyDrop;
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
25
use std::fmt::Debug;
6+
use std::mem::ManuallyDrop;
37

48
#[repr(packed)]
59
pub struct Good {
@@ -50,6 +54,26 @@ fn packed_dyn() {
5054
println!("{:?}", &*foo.0); // no error!
5155
}
5256

57+
// Test for #115396
58+
fn packed_slice_behind_alias() {
59+
trait Mirror {
60+
type Assoc: ?Sized;
61+
}
62+
impl<T: ?Sized> Mirror for T {
63+
type Assoc = T;
64+
}
65+
66+
struct W<T: ?Sized>(<T as Mirror>::Assoc);
67+
68+
#[repr(packed)]
69+
struct Unaligned<T: ?Sized>(ManuallyDrop<W<T>>);
70+
71+
// Even if the actual alignment is 1, we cannot know that when looking at `dyn Debug.`
72+
let ref local: Unaligned<[_; 3]> = Unaligned(ManuallyDrop::new(W([3, 5, 8u8])));
73+
let foo: &Unaligned<[u8]> = local;
74+
let x = &foo.0; // Fine, since the tail of `foo` is `[_]`
75+
}
76+
5377
fn main() {
5478
unsafe {
5579
let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };

0 commit comments

Comments
 (0)