Skip to content

Commit 190ad9c

Browse files
committed
allow #[rustc_align_static(N)] on statics
We need a different attribute than `rustc_align` because unstable attributes are tied to their feature (we can't have two unstable features use the same unstable attribute). Otherwise this uses all of the same infrastructure as `#[rustc_align]`.
1 parent 94722ca commit 190ad9c

File tree

18 files changed

+223
-4
lines changed

18 files changed

+223
-4
lines changed

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
218218
sym::rustc_std_internal_symbol,
219219
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
220220
sym::rustc_align,
221+
sym::rustc_align_static,
221222
// obviously compatible with self
222223
sym::naked,
223224
// documentation

compiler/rustc_attr_parsing/src/attributes/repr.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,30 @@ impl<S: Stage> AttributeParser<S> for AlignParser {
331331
Some(AttributeKind::Align { align, span })
332332
}
333333
}
334+
335+
#[derive(Default)]
336+
pub(crate) struct AlignStaticParser(AlignParser);
337+
338+
impl AlignStaticParser {
339+
const PATH: &'static [Symbol] = &[sym::rustc_align_static];
340+
const TEMPLATE: AttributeTemplate = template!(List: &["<alignment in bytes>"]);
341+
342+
fn parse<'c, S: Stage>(
343+
&mut self,
344+
cx: &'c mut AcceptContext<'_, '_, S>,
345+
args: &'c ArgParser<'_>,
346+
) {
347+
self.0.parse(cx, args)
348+
}
349+
}
350+
351+
impl<S: Stage> AttributeParser<S> for AlignStaticParser {
352+
const ATTRIBUTES: AcceptMapping<Self, S> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
353+
const ALLOWED_TARGETS: AllowedTargets =
354+
AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
355+
356+
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
357+
let (align, span) = self.0.0?;
358+
Some(AttributeKind::Align { align, span })
359+
}
360+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use crate::attributes::proc_macro_attrs::{
4747
ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser,
4848
};
4949
use crate::attributes::prototype::CustomMirParser;
50-
use crate::attributes::repr::{AlignParser, ReprParser};
50+
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
5151
use crate::attributes::rustc_internal::{
5252
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
5353
RustcObjectLifetimeDefaultParser,
@@ -149,6 +149,7 @@ attribute_parsers!(
149149
pub(crate) static ATTRIBUTE_PARSERS = [
150150
// tidy-alphabetical-start
151151
AlignParser,
152+
AlignStaticParser,
152153
BodyStabilityParser,
153154
ConfusablesParser,
154155
ConstStabilityParser,

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
8181
if global.to_rvalue().get_type() != val_llty {
8282
global.to_rvalue().set_type(val_llty);
8383
}
84-
set_global_alignment(self, global, alloc.align);
84+
85+
let align = match attrs.alignment {
86+
Some(alignment) => Ord::max(alignment, alloc.align),
87+
None => alloc.align,
88+
};
89+
set_global_alignment(self, global, align);
8590

8691
global.global_set_initializer_rvalue(value);
8792

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,13 @@ impl<'ll> CodegenCx<'ll, '_> {
452452
self.statics_to_rauw.borrow_mut().push((g, new_g));
453453
new_g
454454
};
455-
set_global_alignment(self, g, alloc.align);
455+
456+
let align = match attrs.alignment {
457+
Some(alignment) => Ord::max(alignment, alloc.align),
458+
None => alloc.align,
459+
};
460+
461+
set_global_alignment(self, g, align);
456462
llvm::set_initializer(g, v);
457463

458464
self.assume_dso_local(g, true);

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
953953

954954
// # Global allocations
955955
if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) {
956-
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
956+
let (size, mut align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
957+
if let GlobalAlloc::Static(def_id) = global_alloc {
958+
if let Some(static_align) = self.tcx.codegen_fn_attrs(def_id).alignment {
959+
align = Ord::max(align, static_align);
960+
}
961+
}
957962
let mutbl = global_alloc.mutability(*self.tcx, self.typing_env);
958963
let kind = match global_alloc {
959964
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
621621
),
622622
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
623623
gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
624+
gated!(rustc_align_static, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)),
624625
ungated!(
625626
unsafe(Edition2024) export_name, Normal,
626627
template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"),

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ declare_features! (
632632
(unstable, simd_ffi, "1.0.0", Some(27731)),
633633
/// Allows specialization of implementations (RFC 1210).
634634
(incomplete, specialization, "1.7.0", Some(31844)),
635+
/// Allows using `#[rustc_align_static(...)]` on static items
636+
(unstable, static_align, "CURRENT_RUSTC_VERSION", Some(146177)),
635637
/// Allows attributes on expressions and non-item statements.
636638
(unstable, stmt_expr_attributes, "1.6.0", Some(15701)),
637639
/// Allows lints part of the strict provenance effort.

compiler/rustc_passes/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,10 @@ passes_repr_align_should_be_align =
501501
`#[repr(align(...))]` is not supported on {$item}
502502
.help = use `#[rustc_align(...)]` instead
503503
504+
passes_repr_align_should_be_align_static =
505+
`#[repr(align(...))]` is not supported on {$item}
506+
.help = use `#[rustc_align_static(...)]` instead
507+
504508
passes_repr_conflicting =
505509
conflicting representation hints
506510

compiler/rustc_passes/src/check_attr.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16081608
item: target.plural_name(),
16091609
});
16101610
}
1611+
Target::Static => {
1612+
if self.tcx.features().static_align() {
1613+
self.dcx().emit_err(errors::ReprAlignShouldBeAlignStatic {
1614+
span: *repr_span,
1615+
item: target.plural_name(),
1616+
});
1617+
}
1618+
}
16111619
_ => {
16121620
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
16131621
hint_span: *repr_span,

0 commit comments

Comments
 (0)