Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 48f8cb4

Browse files
authored
Rollup merge of rust-lang#146178 - folkertdev:static-align, r=jdonszelmann,ralfjung
Implement `#[rustc_align_static(N)]` on `static`s Tracking issue: rust-lang#146177 ```rust #![feature(static_align)] #[rustc_align_static(64)] static SO_ALIGNED: u64 = 0; ``` 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]`. r? ``@traviscross``
2 parents 3c9d5dc + cbacd00 commit 48f8cb4

File tree

21 files changed

+246
-5
lines changed

21 files changed

+246
-5
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 = AlignParser::TEMPLATE;
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
@@ -50,7 +50,7 @@ use crate::attributes::proc_macro_attrs::{
5050
ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser,
5151
};
5252
use crate::attributes::prototype::CustomMirParser;
53-
use crate::attributes::repr::{AlignParser, ReprParser};
53+
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
5454
use crate::attributes::rustc_internal::{
5555
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
5656
RustcObjectLifetimeDefaultParser,
@@ -152,6 +152,7 @@ attribute_parsers!(
152152
pub(crate) static ATTRIBUTE_PARSERS = [
153153
// tidy-alphabetical-start
154154
AlignParser,
155+
AlignStaticParser,
155156
BodyStabilityParser,
156157
ConfusablesParser,
157158
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)