diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/rust/pin-project/tests/repr_packed.rs | |
parent | Initial commit. (diff) | |
download | firefox-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.rs | 52 |
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)); +} |