blob: bc6a9bf8af7dcc3fb615cc79ade269a7131df720 [file] [log] [blame]
#![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())));
}