about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-03 16:09:56 +0000
committerbors <bors@rust-lang.org>2022-08-03 16:09:56 +0000
commitd6b96b61e75dd5ad24a77d6a26a7eef3b492856e (patch)
tree416c2a4dab6081d97b9feba787a2e7fa35c135e7 /src/test
parent04f72f95384d97f4c4e7a59e60cb85ec581ebe06 (diff)
parent9097ce905427c30bd262f62a403f1e987ebb10c6 (diff)
downloadrust-d6b96b61e75dd5ad24a77d6a26a7eef3b492856e.tar.gz
rust-d6b96b61e75dd5ad24a77d6a26a7eef3b492856e.zip
Auto merge of #100064 - RalfJung:disaligned, r=petrochenkov
fix is_disaligned logic for nested packed structs

https://github.com/rust-lang/rust/pull/83605 broke the `is_disaligned` logic by bailing out of the loop in `is_within_packed` early. This PR fixes that problem and adds suitable tests.

Fixes https://github.com/rust-lang/rust/issues/99838
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/issues/issue-99838.rs40
-rw-r--r--src/test/ui/lint/unaligned_references.rs53
-rw-r--r--src/test/ui/lint/unaligned_references.stderr58
3 files changed, 150 insertions, 1 deletions
diff --git a/src/test/ui/issues/issue-99838.rs b/src/test/ui/issues/issue-99838.rs
new file mode 100644
index 00000000000..eaeeac72b25
--- /dev/null
+++ b/src/test/ui/issues/issue-99838.rs
@@ -0,0 +1,40 @@
+// run-pass
+#![feature(bench_black_box)]
+use std::hint;
+
+struct U16(u16);
+
+impl Drop for U16 {
+    fn drop(&mut self) {
+        // Prevent LLVM from optimizing away our alignment check.
+        assert!(hint::black_box(self as *mut U16 as usize) % 2 == 0);
+    }
+}
+
+struct HasDrop;
+
+impl Drop for HasDrop {
+    fn drop(&mut self) {}
+}
+
+struct Wrapper {
+    _a: U16,
+    b: HasDrop,
+}
+
+#[repr(packed)]
+struct Misalign(u8, Wrapper);
+
+fn main() {
+    let m = Misalign(
+        0,
+        Wrapper {
+            _a: U16(10),
+            b: HasDrop,
+        },
+    );
+    // Put it somewhere definitely even (so the `a` field is definitely at an odd address).
+    let m: ([u16; 0], Misalign) = ([], m);
+    // Move out one field, so we run custom per-field drop logic below.
+    let _x = m.1.1.b;
+}
diff --git a/src/test/ui/lint/unaligned_references.rs b/src/test/ui/lint/unaligned_references.rs
index d06b06b504f..e547f031a9c 100644
--- a/src/test/ui/lint/unaligned_references.rs
+++ b/src/test/ui/lint/unaligned_references.rs
@@ -47,4 +47,57 @@ fn main() {
         let _ = &packed2.y; // ok, has align 2 in packed(2) struct
         let _ = &packed2.z; // ok, has align 1
     }
+
+    unsafe {
+        struct U16(u16);
+
+        impl Drop for U16 {
+            fn drop(&mut self) {
+                println!("{:p}", self);
+            }
+        }
+
+        struct HasDrop;
+
+        impl Drop for HasDrop {
+            fn drop(&mut self) {}
+        }
+
+        #[allow(unused)]
+        struct Wrapper {
+            a: U16,
+            b: HasDrop,
+        }
+        #[allow(unused)]
+        #[repr(packed(2))]
+        struct Wrapper2 {
+            a: U16,
+            b: HasDrop,
+        }
+
+        // An outer struct with more restrictive packing than the inner struct -- make sure we
+        // notice that!
+        #[repr(packed)]
+        struct Misalign<T>(u8, T);
+
+        let m1 = Misalign(
+            0,
+            Wrapper {
+                a: U16(10),
+                b: HasDrop,
+            },
+        );
+        let _ref = &m1.1.a; //~ ERROR reference to packed field
+        //~^ previously accepted
+
+        let m2 = Misalign(
+            0,
+            Wrapper2 {
+                a: U16(10),
+                b: HasDrop,
+            },
+        );
+        let _ref = &m2.1.a; //~ ERROR reference to packed field
+        //~^ previously accepted
+    }
 }
diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr
index ed5dd2ec011..97dbec2861c 100644
--- a/src/test/ui/lint/unaligned_references.stderr
+++ b/src/test/ui/lint/unaligned_references.stderr
@@ -80,7 +80,29 @@ LL |         let _ = &packed2.x;
    = note: fields of packed structs are not properly aligned, and 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: aborting due to 7 previous errors
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:90:20
+   |
+LL |         let _ref = &m1.1.a;
+   |                    ^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and 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: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:100:20
+   |
+LL |         let _ref = &m2.1.a;
+   |                    ^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and 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: aborting due to 9 previous errors
 
 Future incompatibility report: Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -201,3 +223,37 @@ LL | #![deny(unaligned_references)]
    = note: fields of packed structs are not properly aligned, and 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)
 
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:90:20
+   |
+LL |         let _ref = &m1.1.a;
+   |                    ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and 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)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:100:20
+   |
+LL |         let _ref = &m2.1.a;
+   |                    ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and 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)
+