| #![feature(static_align)] |
| #![deny(non_upper_case_globals)] |
| |
| use std::cell::Cell; |
| |
| // When a static uses `align(N)`, its address should be a multiple of `N`. |
| |
| #[rustc_align_static(256)] |
| static FOO: u64 = 0; |
| |
| #[rustc_align_static(512)] |
| static BAR: u64 = 0; |
| |
| struct HasDrop(*const HasDrop); |
| |
| impl Drop for HasDrop { |
| fn drop(&mut self) { |
| assert_eq!(core::ptr::from_mut(self).cast_const(), self.0); |
| } |
| } |
| |
| thread_local! { |
| #[rustc_align_static(4096)] |
| static LOCAL: u64 = 0; |
| |
| #[allow(unused_mut, reason = "test attribute handling")] |
| #[cfg_attr(true, rustc_align_static(4096))] |
| static CONST_LOCAL: u64 = const { 0 }; |
| |
| #[cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096)))] |
| #[allow(unused_mut, reason = "test attribute handling")] |
| static HASDROP_LOCAL: Cell<HasDrop> = Cell::new(HasDrop(core::ptr::null())); |
| |
| /// I love doc comments. |
| #[allow(unused_mut, reason = "test attribute handling")] |
| #[cfg_attr(all(), |
| cfg_attr(any(true), |
| cfg_attr(true, rustc_align_static(4096))))] |
| #[allow(unused_mut, reason = "test attribute handling")] |
| /// I love doc comments. |
| static HASDROP_CONST_LOCAL: Cell<HasDrop> = const { Cell::new(HasDrop(core::ptr::null())) }; |
| |
| #[cfg_attr(true,)] |
| #[cfg_attr(false,)] |
| #[cfg_attr( |
| true, |
| rustc_align_static(32), |
| cfg_attr(true, allow(non_upper_case_globals, reason = "test attribute handling")), |
| cfg_attr(false,) |
| )] |
| #[cfg_attr(false, rustc_align_static(0))] |
| static more_attr_testing: u64 = 0; |
| } |
| |
| fn thread_local_ptr<T>(key: &'static std::thread::LocalKey<T>) -> *const T { |
| key.with(|local| core::ptr::from_ref::<T>(local)) |
| } |
| |
| fn main() { |
| assert!(core::ptr::from_ref(&FOO).addr().is_multiple_of(256)); |
| assert!(core::ptr::from_ref(&BAR).addr().is_multiple_of(512)); |
| |
| assert!(thread_local_ptr(&LOCAL).addr().is_multiple_of(4096)); |
| assert!(thread_local_ptr(&CONST_LOCAL).addr().is_multiple_of(4096)); |
| assert!(thread_local_ptr(&HASDROP_LOCAL).addr().is_multiple_of(4096)); |
| assert!(thread_local_ptr(&HASDROP_CONST_LOCAL).addr().is_multiple_of(4096)); |
| assert!(thread_local_ptr(&more_attr_testing).addr().is_multiple_of(32)); |
| |
| // Test that address (and therefore alignment) is maintained during drop |
| let hasdrop_ptr = thread_local_ptr(&HASDROP_LOCAL); |
| core::mem::forget(HASDROP_LOCAL.replace(HasDrop(hasdrop_ptr.cast()))); |
| let hasdrop_const_ptr = thread_local_ptr(&HASDROP_CONST_LOCAL); |
| core::mem::forget(HASDROP_CONST_LOCAL.replace(HasDrop(hasdrop_const_ptr.cast()))); |
| } |