From 97a7b9b1b498ca60ef68376fc34a61a001a0fea6 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 29 Jun 2025 12:50:21 -0400 Subject: [PATCH 1/7] Remove `repr(align)` code --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 10 +------ compiler/rustc_passes/messages.ftl | 4 +++ compiler/rustc_passes/src/check_attr.rs | 5 +--- compiler/rustc_passes/src/errors.rs | 9 +++++++ tests/ui/attributes/malformed-fn-align.rs | 9 +++++++ tests/ui/attributes/malformed-fn-align.stderr | 26 ++++++++++++++++++- 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index be63bb8ac59f1..ff4544278714f 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -4,7 +4,7 @@ use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; use rustc_attr_data_structures::{ - AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, UsedBy, find_attr, + AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, UsedBy, find_attr, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; @@ -109,14 +109,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let hir::Attribute::Parsed(p) = attr { match p { - AttributeKind::Repr { reprs, first_span: _ } => { - codegen_fn_attrs.alignment = reprs - .iter() - .filter_map( - |(r, _)| if let ReprAttr::ReprAlign(x) = r { Some(*x) } else { None }, - ) - .max(); - } AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, AttributeKind::ExportName { name, .. } => { codegen_fn_attrs.export_name = Some(*name); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 5a94d01e08866..46c21dcf67b19 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -13,6 +13,10 @@ passes_abi_ne = passes_abi_of = fn_abi_of({$fn_name}) = {$fn_abi} +passes_align_attr_application = + `#[align(...)]` should be applied to a function item + .label = not a function item + passes_align_should_be_repr_align = `#[align(...)]` is not supported on {$item} items .suggestion = use `#[repr(align(...))]` instead diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3fa5cdc36bce9..3d9eac0aedce8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1924,10 +1924,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }); } _ => { - self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { - hint_span: repr_span, - span, - }); + self.dcx().emit_err(errors::AlignAttrApplication { hint_span: repr_span, span }); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3ede3c889c8a1..4ad615a2abfc8 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1838,3 +1838,12 @@ pub(crate) struct AlignShouldBeReprAlign { pub item: &'static str, pub align_bytes: u64, } + +#[derive(Diagnostic)] +#[diag(passes_align_attr_application)] +pub(crate) struct AlignAttrApplication { + #[primary_span] + pub hint_span: Span, + #[label] + pub span: Span, +} diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index f5ab9555e561f..870bc34d45484 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -23,3 +23,12 @@ fn f4() {} #[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items struct S1; + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +const FOO: i32 = 42; + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +mod test {} + +#[align(32)] //~ ERROR `#[align(...)]` should be applied to a function item +use ::std::iter; diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index b769d0b457ddd..e1fe5353a4100 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -61,7 +61,31 @@ LL - #[align(16)] LL + #[repr(align(16))] | -error: aborting due to 7 previous errors +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:27:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | const FOO: i32 = 42; + | -------------------- not a function item + +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:30:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | mod test {} + | ----------- not a function item + +error: `#[align(...)]` should be applied to a function item + --> $DIR/malformed-fn-align.rs:33:1 + | +LL | #[align(32)] + | ^^^^^^^^^^^^ +LL | use ::std::iter; + | ---------------- not a function item + +error: aborting due to 10 previous errors Some errors have detailed explanations: E0539, E0589, E0805. For more information about an error, try `rustc --explain E0539`. From a1cefee8d5d39e7e36b60ea0cca06c0220938f74 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 29 Jun 2025 13:01:41 -0400 Subject: [PATCH 2/7] =?UTF-8?q?Support=20`#[align(=E2=80=A6)]`=20on=20fns?= =?UTF-8?q?=20in=20`extern`=20blocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_passes/src/check_attr.rs | 2 +- tests/codegen/align-fn.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3d9eac0aedce8..b8f1ec7ca9350 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1915,7 +1915,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks if the `#[align]` attributes on `item` are valid. fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) { match target { - Target::Fn | Target::Method(_) => {} + Target::Fn | Target::Method(_) | Target::ForeignFn => {} Target::Struct | Target::Union | Target::Enum => { self.dcx().emit_err(errors::AlignShouldBeReprAlign { span: repr_span, diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index 90073ff308143..4a9fc49d2113d 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -116,3 +116,17 @@ pub fn align_specified_twice_2() {} #[align(32)] #[align(256)] pub fn align_specified_twice_3() {} + +const _: () = { + // CHECK-LABEL: align_unmangled + // CHECK-SAME: align 256 + #[unsafe(no_mangle)] + #[align(32)] + #[align(256)] + extern "C" fn align_unmangled() {} +}; + +unsafe extern "C" { + #[align(256)] + fn align_unmangled(); +} From ce8ab082cc327cf2064c0037fd39f2081397f9f6 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 29 Jun 2025 14:23:02 -0400 Subject: [PATCH 3/7] Test `async fn` --- tests/codegen/align-fn.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index 4a9fc49d2113d..6f26ebe66f226 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -1,4 +1,5 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code +//@ edition: 2024 #![crate_type = "lib"] #![feature(fn_align)] @@ -130,3 +131,9 @@ unsafe extern "C" { #[align(256)] fn align_unmangled(); } + +// CHECK-LABEL: async_align +// CHECK-SAME: align 64 +#[unsafe(no_mangle)] +#[align(64)] +pub async fn async_align() {} From a144fd64bb339410806122c26da9e824a4a35a2a Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 29 Jun 2025 14:33:51 -0400 Subject: [PATCH 4/7] Add test for `dyn` alignment --- tests/ui/attributes/fn-align-dyn.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/ui/attributes/fn-align-dyn.rs diff --git a/tests/ui/attributes/fn-align-dyn.rs b/tests/ui/attributes/fn-align-dyn.rs new file mode 100644 index 0000000000000..d67de05e7a9fd --- /dev/null +++ b/tests/ui/attributes/fn-align-dyn.rs @@ -0,0 +1,15 @@ +//@ run-pass +#![feature(fn_align)] + +trait Test { + #[align(4096)] + fn foo(&self); + + #[align(4096)] + fn foo1(&self); +} + +fn main() { + assert_eq!((::foo as fn(_) as usize & !1) % 4096, 0); + assert_eq!((::foo1 as fn(_) as usize & !1) % 4096, 0); +} From 1c93e16c10ef18e4c4da27772899bf8c64d9eaf3 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 1 Jul 2025 15:58:23 -0400 Subject: [PATCH 5/7] Add FIXME for gen et al --- tests/codegen/align-fn.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index 6f26ebe66f226..c871d1259507f 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -132,6 +132,7 @@ unsafe extern "C" { fn align_unmangled(); } +// FIXME also check `gen` et al // CHECK-LABEL: async_align // CHECK-SAME: align 64 #[unsafe(no_mangle)] From 196e3ed94357c29d2b29386023e19cc6cc83a175 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 1 Jul 2025 16:13:37 -0400 Subject: [PATCH 6/7] Add more tests for invalid alignments --- tests/ui/attributes/malformed-fn-align.rs | 15 +++++++ tests/ui/attributes/malformed-fn-align.stderr | 42 ++++++++++++++++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index 870bc34d45484..e06e611684242 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -21,6 +21,21 @@ fn f3() {} #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items fn f4() {} +#[align(-1)] //~ ERROR expected unsuffixed literal, found `-` +fn f5() {} + +#[align(3)] //~ ERROR invalid alignment value: not a power of two +fn f6() {} + +#[align(4usize)] //~ ERROR invalid alignment value: not an unsuffixed integer [E0589] +//~^ ERROR suffixed literals are not allowed in attributes +fn f7() {} + +#[align(16)] +#[align(3)] //~ ERROR invalid alignment value: not a power of two +#[align(16)] +fn f8() {} + #[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items struct S1; diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index e1fe5353a4100..af3625b1f3b9e 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -1,3 +1,17 @@ +error: expected unsuffixed literal, found `-` + --> $DIR/malformed-fn-align.rs:24:9 + | +LL | #[align(-1)] + | ^ + +error: suffixed literals are not allowed in attributes + --> $DIR/malformed-fn-align.rs:30:9 + | +LL | #[align(4usize)] + | ^^^^^^ + | + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) + error[E0539]: malformed `align` attribute input --> $DIR/malformed-fn-align.rs:5:5 | @@ -37,6 +51,24 @@ error[E0589]: invalid alignment value: not a power of two LL | #[align(0)] | ^ +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-fn-align.rs:27:9 + | +LL | #[align(3)] + | ^ + +error[E0589]: invalid alignment value: not an unsuffixed integer + --> $DIR/malformed-fn-align.rs:30:9 + | +LL | #[align(4usize)] + | ^^^^^^ + +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-fn-align.rs:35:9 + | +LL | #[align(3)] + | ^ + error: `#[repr(align(...))]` is not supported on function items --> $DIR/malformed-fn-align.rs:21:8 | @@ -50,7 +82,7 @@ LL | #[repr(align(16))] | ^^^^^^^^^ error: `#[align(...)]` is not supported on struct items - --> $DIR/malformed-fn-align.rs:24:1 + --> $DIR/malformed-fn-align.rs:39:1 | LL | #[align(16)] | ^^^^^^^^^^^^ @@ -62,7 +94,7 @@ LL + #[repr(align(16))] | error: `#[align(...)]` should be applied to a function item - --> $DIR/malformed-fn-align.rs:27:1 + --> $DIR/malformed-fn-align.rs:42:1 | LL | #[align(32)] | ^^^^^^^^^^^^ @@ -70,7 +102,7 @@ LL | const FOO: i32 = 42; | -------------------- not a function item error: `#[align(...)]` should be applied to a function item - --> $DIR/malformed-fn-align.rs:30:1 + --> $DIR/malformed-fn-align.rs:45:1 | LL | #[align(32)] | ^^^^^^^^^^^^ @@ -78,14 +110,14 @@ LL | mod test {} | ----------- not a function item error: `#[align(...)]` should be applied to a function item - --> $DIR/malformed-fn-align.rs:33:1 + --> $DIR/malformed-fn-align.rs:48:1 | LL | #[align(32)] | ^^^^^^^^^^^^ LL | use ::std::iter; | ---------------- not a function item -error: aborting due to 10 previous errors +error: aborting due to 15 previous errors Some errors have detailed explanations: E0539, E0589, E0805. For more information about an error, try `rustc --explain E0539`. From 8f86c4abec54ecc06b469fff2cccf0a4182db41d Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 6 Jul 2025 18:10:52 -0400 Subject: [PATCH 7/7] Skip `align` tests on wasm --- tests/assembly/naked-functions/wasm32.rs | 10 ++++------ tests/codegen/align-fn.rs | 1 + tests/codegen/min-function-alignment.rs | 1 + tests/codegen/naked-fn/aligned.rs | 1 + tests/codegen/naked-fn/min-function-alignment.rs | 1 + tests/ui/attributes/fn-align-dyn.rs | 1 + 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs index 5f114246ad557..77547e82041fe 100644 --- a/tests/assembly/naked-functions/wasm32.rs +++ b/tests/assembly/naked-functions/wasm32.rs @@ -27,18 +27,16 @@ extern "C" fn nop() { naked_asm!("nop") } -// CHECK: .section .text.weak_aligned_nop,"",@ -// CHECK: .weak weak_aligned_nop +// CHECK: .section .text.weak_nop,"",@ +// CHECK: .weak weak_nop // CHECK-LABEL: nop: -// CHECK: .functype weak_aligned_nop () -> () +// CHECK: .functype weak_nop () -> () // CHECK-NOT: .size // CHECK: end_function #[no_mangle] #[unsafe(naked)] #[linkage = "weak"] -// wasm functions cannot be aligned, so this has no effect -#[align(32)] -extern "C" fn weak_aligned_nop() { +extern "C" fn weak_nop() { naked_asm!("nop") } diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index c871d1259507f..fd572910c287f 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -1,5 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code //@ edition: 2024 +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs index 78989ec5df236..6a3843b0f4f59 100644 --- a/tests/codegen/min-function-alignment.rs +++ b/tests/codegen/min-function-alignment.rs @@ -2,6 +2,7 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code //@ [align16] compile-flags: -Zmin-function-alignment=16 //@ [align1024] compile-flags: -Zmin-function-alignment=1024 +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs index f9fce8e5a5d59..2648b0213ca86 100644 --- a/tests/codegen/naked-fn/aligned.rs +++ b/tests/codegen/naked-fn/aligned.rs @@ -1,6 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 //@ needs-asm-support //@ ignore-arm no "ret" mnemonic +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![crate_type = "lib"] #![feature(fn_align)] diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs index 59554c1cae554..4ebaacd3eff79 100644 --- a/tests/codegen/naked-fn/min-function-alignment.rs +++ b/tests/codegen/naked-fn/min-function-alignment.rs @@ -1,6 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16 //@ needs-asm-support //@ ignore-arm no "ret" mnemonic +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![feature(fn_align)] #![crate_type = "lib"] diff --git a/tests/ui/attributes/fn-align-dyn.rs b/tests/ui/attributes/fn-align-dyn.rs index d67de05e7a9fd..8ba4d5e2897df 100644 --- a/tests/ui/attributes/fn-align-dyn.rs +++ b/tests/ui/attributes/fn-align-dyn.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) #![feature(fn_align)] trait Test {