blob: e2db7c01adf29cf4b48cb03986c686fcf5dcf11b [file] [log] [blame]
//@ run-pass
//@ compile-flags: --cfg FOURTY_TWO="42" --cfg TRUE --check-cfg=cfg(FOURTY_TWO,values("42")) --check-cfg=cfg(TRUE)
#![feature(static_align)]
#![deny(non_upper_case_globals)]
use std::cell::Cell;
#[rustc_align_static(64)]
static A: u8 = 0;
#[rustc_align_static(4096)]
static B: u8 = 0;
#[rustc_align_static(128)]
#[no_mangle]
static EXPORTED: u64 = 0;
unsafe extern "C" {
#[rustc_align_static(128)]
#[link_name = "EXPORTED"]
static C: u64;
}
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.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
#[allow(unused_mut, reason = "test attribute handling")]
#[cfg_attr(TRUE,
cfg_attr(FOURTY_TWO = "42",
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.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
/// I love doc comments.
static HASDROP_CONST_LOCAL: Cell<HasDrop> = const { Cell::new(HasDrop(core::ptr::null())) };
#[cfg_attr(TRUE,)]
#[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(&A).addr().is_multiple_of(64));
assert!(core::ptr::from_ref(&B).addr().is_multiple_of(4096));
assert!(core::ptr::from_ref(&EXPORTED).addr().is_multiple_of(128));
unsafe { assert!(core::ptr::from_ref(&C).addr().is_multiple_of(128)) };
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())));
}