still accept references to u8 slices and str in packed fields
This commit is contained in:
parent
8b3435c10f
commit
ad7045e160
@ -21,12 +21,18 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let ty = place.ty(local_decls, tcx).ty;
|
let ty = place.ty(local_decls, tcx).ty;
|
||||||
|
let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
|
||||||
match tcx.layout_of(param_env.and(ty)) {
|
match tcx.layout_of(param_env.and(ty)) {
|
||||||
Ok(layout) if layout.align.abi <= pack && layout.is_sized() => {
|
Ok(layout)
|
||||||
|
if layout.align.abi <= pack
|
||||||
|
&& (layout.is_sized()
|
||||||
|
|| matches!(unsized_tail().kind(), ty::Slice(..) | ty::Str)) =>
|
||||||
|
{
|
||||||
// If the packed alignment is greater or equal to the field alignment, the type won't be
|
// If the packed alignment is greater or equal to the field alignment, the type won't be
|
||||||
// further disaligned.
|
// further disaligned.
|
||||||
// However we need to ensure the field is sized; for unsized fields, `layout.align` is
|
// However we need to ensure the field is sized; for unsized fields, `layout.align` is
|
||||||
// just an approximation.
|
// just an approximation -- except when the unsized tail is a slice, where the alignment
|
||||||
|
// is fully determined by the type.
|
||||||
debug!(
|
debug!(
|
||||||
"is_disaligned({:?}) - align = {}, packed = {}; not disaligned",
|
"is_disaligned({:?}) - align = {}, packed = {}; not disaligned",
|
||||||
place,
|
place,
|
||||||
|
@ -38,6 +38,16 @@ fn packed_dyn() {
|
|||||||
let ref local = Unaligned(ManuallyDrop::new([3, 5, 8u64]));
|
let ref local = Unaligned(ManuallyDrop::new([3, 5, 8u64]));
|
||||||
let foo: &Unaligned<dyn Debug> = &*local;
|
let foo: &Unaligned<dyn Debug> = &*local;
|
||||||
println!("{:?}", &*foo.0); //~ ERROR reference to packed field
|
println!("{:?}", &*foo.0); //~ ERROR reference to packed field
|
||||||
|
let foo: &Unaligned<[u64]> = &*local;
|
||||||
|
println!("{:?}", &*foo.0); //~ ERROR reference to packed field
|
||||||
|
|
||||||
|
// Even if the actual alignment is 1, we cannot know that when looking at `dyn Debug.`
|
||||||
|
let ref local = Unaligned(ManuallyDrop::new([3, 5, 8u8]));
|
||||||
|
let foo: &Unaligned<dyn Debug> = &*local;
|
||||||
|
println!("{:?}", &*foo.0); //~ ERROR reference to packed field
|
||||||
|
// However, we *can* know the alignment when looking at a slice.
|
||||||
|
let foo: &Unaligned<[u8]> = &*local;
|
||||||
|
println!("{:?}", &*foo.0); // no error!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -19,7 +19,27 @@ LL | println!("{:?}", &*foo.0);
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:47:17
|
--> $DIR/unaligned_references.rs:42:24
|
||||||
|
|
|
||||||
|
LL | println!("{:?}", &*foo.0);
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||||
|
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= 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)
|
||||||
|
|
||||||
|
error[E0793]: reference to packed field is unaligned
|
||||||
|
--> $DIR/unaligned_references.rs:47:24
|
||||||
|
|
|
||||||
|
LL | println!("{:?}", &*foo.0);
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||||
|
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= 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)
|
||||||
|
|
||||||
|
error[E0793]: reference to packed field is unaligned
|
||||||
|
--> $DIR/unaligned_references.rs:57:17
|
||||||
|
|
|
|
||||||
LL | let _ = &good.ptr;
|
LL | let _ = &good.ptr;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -29,7 +49,7 @@ LL | let _ = &good.ptr;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:48:17
|
--> $DIR/unaligned_references.rs:58:17
|
||||||
|
|
|
|
||||||
LL | let _ = &good.data;
|
LL | let _ = &good.data;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -39,7 +59,7 @@ LL | let _ = &good.data;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:50:17
|
--> $DIR/unaligned_references.rs:60:17
|
||||||
|
|
|
|
||||||
LL | let _ = &good.data as *const _;
|
LL | let _ = &good.data as *const _;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -49,7 +69,7 @@ LL | let _ = &good.data as *const _;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:51:27
|
--> $DIR/unaligned_references.rs:61:27
|
||||||
|
|
|
|
||||||
LL | let _: *const _ = &good.data;
|
LL | let _: *const _ = &good.data;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -59,7 +79,7 @@ LL | let _: *const _ = &good.data;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:53:17
|
--> $DIR/unaligned_references.rs:63:17
|
||||||
|
|
|
|
||||||
LL | let _ = good.data.clone();
|
LL | let _ = good.data.clone();
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -69,7 +89,7 @@ LL | let _ = good.data.clone();
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:55:17
|
--> $DIR/unaligned_references.rs:65:17
|
||||||
|
|
|
|
||||||
LL | let _ = &good.data2[0];
|
LL | let _ = &good.data2[0];
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
@ -79,7 +99,7 @@ LL | let _ = &good.data2[0];
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:64:17
|
--> $DIR/unaligned_references.rs:74:17
|
||||||
|
|
|
|
||||||
LL | let _ = &packed2.x;
|
LL | let _ = &packed2.x;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -89,7 +109,7 @@ LL | let _ = &packed2.x;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:103:20
|
--> $DIR/unaligned_references.rs:113:20
|
||||||
|
|
|
|
||||||
LL | let _ref = &m1.1.a;
|
LL | let _ref = &m1.1.a;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
@ -99,7 +119,7 @@ LL | let _ref = &m1.1.a;
|
|||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error[E0793]: reference to packed field is unaligned
|
error[E0793]: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:106:20
|
--> $DIR/unaligned_references.rs:116:20
|
||||||
|
|
|
|
||||||
LL | let _ref = &m2.1.a;
|
LL | let _ref = &m2.1.a;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
@ -108,6 +128,6 @@ LL | let _ref = &m2.1.a;
|
|||||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
= 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)
|
= 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)
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0793`.
|
For more information about this error, try `rustc --explain E0793`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user