Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit af834f3

Browse files
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 c559c4a commit af834f3

File tree

21 files changed

+247
-4
lines changed

21 files changed

+247
-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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ 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+
85+
// NOTE: Alignment from attributes has already been applied to the allocation.
8486
set_global_alignment(self, global, alloc.align);
8587

8688
global.global_set_initializer_rvalue(value);

‎compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ impl<'ll> CodegenCx<'ll, '_> {
452452
self.statics_to_rauw.borrow_mut().push((g, new_g));
453453
new_g
454454
};
455+
456+
// NOTE: Alignment from attributes has already been applied to the allocation.
455457
set_global_alignment(self, g, alloc.align);
456458
llvm::set_initializer(g, v);
457459

‎compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ 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+
// NOTE: `static` alignment from attributes has already been applied to the allocation.
956957
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
957958
let mutbl = global_alloc.mutability(*self.tcx, self.typing_env);
958959
let kind = match global_alloc {

‎compiler/rustc_const_eval/src/interpret/util.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_hir::def_id::LocalDefId;
22
use rustc_middle::mir;
3-
use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer};
3+
use rustc_middle::mir::interpret::{AllocInit, Allocation, GlobalAlloc,InterpResult, Pointer};
44
use rustc_middle::ty::layout::TyAndLayout;
55
use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt};
66
use tracing::debug;
@@ -38,7 +38,14 @@ pub(crate) fn create_static_alloc<'tcx>(
3838
static_def_id: LocalDefId,
3939
layout: TyAndLayout<'tcx>,
4040
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
41-
let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit, ())?;
41+
// Inherit size and align from the `GlobalAlloc::Static` so we can avoid duplicating
42+
// the alignment attribute logic.
43+
let (size, align) =
44+
GlobalAlloc::Static(static_def_id.into()).size_and_align(*ecx.tcx, ecx.typing_env);
45+
assert_eq!(size, layout.size);
46+
assert!(align >= layout.align.abi);
47+
48+
let alloc = Allocation::try_new(size, align, AllocInit::Uninit, ())?;
4249
let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into());
4350
assert_eq!(ecx.machine.static_root_ids, None);
4451
ecx.machine.static_root_ids = Some((alloc_id, static_def_id));

‎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_middle/src/mir/interpret/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,16 @@ impl<'tcx> GlobalAlloc<'tcx> {
386386
.expect("statics should not have generic parameters");
387387
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
388388
assert!(layout.is_sized());
389-
(layout.size, layout.align.abi)
389+
390+
// Take over-alignment from attributes into account.
391+
let align = match tcx.codegen_fn_attrs(def_id).alignment {
392+
Some(align_from_attribute) => {
393+
Ord::max(align_from_attribute, layout.align.abi)
394+
}
395+
None => layout.align.abi,
396+
};
397+
398+
(layout.size, align)
390399
}
391400
}
392401
GlobalAlloc::Memory(alloc) => {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /