summaryrefslogtreecommitdiffstats
path: root/third_party/rust/pin-project/tests/repr_packed.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/rust/pin-project/tests/repr_packed.rs
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/pin-project/tests/repr_packed.rs')
-rw-r--r--third_party/rust/pin-project/tests/repr_packed.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/third_party/rust/pin-project/tests/repr_packed.rs b/third_party/rust/pin-project/tests/repr_packed.rs
new file mode 100644
index 0000000000..be7cab975f
--- /dev/null
+++ b/third_party/rust/pin-project/tests/repr_packed.rs
@@ -0,0 +1,52 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+// unaligned_references did not exist in older compilers and safe_packed_borrows was removed in the latest compilers.
+// https://github.com/rust-lang/rust/pull/82525
+#![allow(unknown_lints, renamed_and_removed_lints)]
+#![forbid(unaligned_references, safe_packed_borrows)]
+
+use std::cell::Cell;
+
+// Ensure that the compiler doesn't copy the fields
+// of #[repr(packed)] types during drop, if the field has alignment 1
+// (that is, any reference to the field is guaranteed to have proper alignment)
+// We are currently unable to statically prevent the usage of #[pin_project]
+// on #[repr(packed)] types composed entirely of fields of alignment 1.
+// This shouldn't lead to undefined behavior, as long as the compiler doesn't
+// try to move the field anyway during drop.
+//
+// This tests validates that the compiler is doing what we expect.
+#[test]
+fn weird_repr_packed() {
+ // We keep track of the field address during
+ // drop using a thread local, to avoid changing
+ // the layout of our #[repr(packed)] type.
+ thread_local! {
+ static FIELD_ADDR: Cell<usize> = Cell::new(0);
+ }
+
+ #[repr(packed)]
+ struct Struct {
+ field: u8,
+ }
+
+ impl Drop for Struct {
+ fn drop(&mut self) {
+ FIELD_ADDR.with(|f| {
+ f.set(&self.field as *const u8 as usize);
+ });
+ }
+ }
+
+ #[allow(clippy::let_and_return)]
+ let field_addr = {
+ // We let this field drop by going out of scope,
+ // rather than explicitly calling drop(foo).
+ // Calling drop(foo) causes 'foo' to be moved
+ // into the 'drop' function, resulting in a different
+ // address.
+ let x = Struct { field: 27 };
+ let field_addr = &x.field as *const u8 as usize;
+ field_addr
+ };
+ assert_eq!(field_addr, FIELD_ADDR.with(Cell::get));
+}