diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index e8c42d16733ec..d445e738d012b 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -475,10 +475,10 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx); attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]); } - // function alignment can be set globally with the `-Zmin-function-alignment=` flag; + // function alignment can be set globally with the `-Cmin-function-alignment=` flag; // the alignment from a `#[repr(align())]` is used if it specifies a higher alignment. if let Some(align) = - Ord::max(cx.tcx.sess.opts.unstable_opts.min_function_alignment, codegen_fn_attrs.alignment) + Ord::max(cx.tcx.sess.opts.cg.min_function_alignment, codegen_fn_attrs.alignment) { llvm::set_alignment(llfn, align); } diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 3a6b1f8d4efc9..efad87d85556b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -121,10 +121,10 @@ fn prefix_and_suffix<'tcx>( let attrs = tcx.codegen_fn_attrs(instance.def_id()); let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string()); - // function alignment can be set globally with the `-Zmin-function-alignment=` flag; + // Function alignment can be set globally with the `-Cmin-function-alignment=` flag; // the alignment from a `#[repr(align())]` is used if it specifies a higher alignment. // if no alignment is specified, an alignment of 4 bytes is used. - let min_function_alignment = tcx.sess.opts.unstable_opts.min_function_alignment; + let min_function_alignment = tcx.sess.opts.cg.min_function_alignment; let align_bytes = Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4); diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9d8130661b04d..a31a0ffb5ac07 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -875,10 +875,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if let Some(fn_val) = self.get_fn_alloc(id) { let align = match fn_val { FnVal::Instance(instance) => { - // Function alignment can be set globally with the `-Zmin-function-alignment=` flag; + // Function alignment can be set globally with the `-Cmin-function-alignment=` flag; // the alignment from a `#[repr(align())]` is used if it specifies a higher alignment. let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment; - let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment; + let global_align = self.tcx.sess.opts.cg.min_function_alignment; Ord::max(global_align, fn_align).unwrap_or(Align::ONE) } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index e3e4eefe5e10a..a8c77b5ef1173 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -214,6 +214,8 @@ declare_features! ( (accepted, f16c_target_feature, "1.68.0", Some(44839)), /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. (accepted, field_init_shorthand, "1.17.0", Some(37340)), + /// Allows using `#[repr(align(...))]` on function items + (accepted, fn_align, "CURRENT_RUSTC_VERSION", Some(82232)), /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940). (accepted, fn_must_use, "1.27.0", Some(43302)), /// Allows capturing variables in scope using format_args! diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index cbc121e3632a6..fcee0d977c0c8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -496,8 +496,6 @@ declare_features! ( (unstable, ffi_pure, "1.45.0", Some(58329)), /// Controlling the behavior of fmt::Debug (unstable, fmt_debug, "1.82.0", Some(129709)), - /// Allows using `#[repr(align(...))]` on function items - (unstable, fn_align, "1.53.0", Some(82232)), /// Support delegating implementation of functions to other already implemented functions. (incomplete, fn_delegation, "1.76.0", Some(118212)), /// Allows impls for the Freeze trait. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 5c8c51c8bbcc2..7d822930e11ce 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -624,6 +624,7 @@ fn test_codegen_options_tracking_hash() { tracked!(llvm_args, vec![String::from("1"), String::from("2")]); tracked!(lto, LtoCli::Fat); tracked!(metadata, vec![String::from("A"), String::from("B")]); + tracked!(min_function_alignment, Some(Align::EIGHT)); tracked!(no_prepopulate_passes, true); tracked!(no_redzone, Some(true)); tracked!(no_vectorize_loops, true); @@ -815,7 +816,6 @@ fn test_unstable_options_tracking_hash() { tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); tracked!(maximal_hir_to_mir_coverage, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); - tracked!(min_function_alignment, Some(Align::EIGHT)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); tracked!(mir_opt_level, Some(4)); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 413726ddd82d3..ed1575cdeec9b 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -629,9 +629,6 @@ passes_remove_fields = *[other] fields } -passes_repr_align_function = - `repr(align)` attributes on functions are unstable - passes_repr_align_greater_than_target_max = alignment must not be greater than `isize::MAX` bytes .note = `isize::MAX` is {$size} for the current target diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index cfc71a412bea2..2b3924606f294 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1975,17 +1975,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ReprAttr::ReprAlign(align) => { match target { Target::Struct | Target::Union | Target::Enum => {} - Target::Fn | Target::Method(_) => { - if !self.tcx.features().fn_align() { - feature_err( - &self.tcx.sess, - sym::fn_align, - *repr_span, - fluent::passes_repr_align_function, - ) - .emit(); - } - } + Target::Fn | Target::Method(_) => {} _ => { self.dcx().emit_err( errors::AttrApplication::StructEnumFunctionMethodUnion { @@ -2049,15 +2039,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if item.is_some() { match target { Target::Struct | Target::Union | Target::Enum => continue, - Target::Fn | Target::Method(_) => { - feature_err( - &self.tcx.sess, - sym::fn_align, - *repr_span, - fluent::passes_repr_align_function, - ) - .emit(); - } + Target::Fn | Target::Method(_) => continue, _ => { self.dcx().emit_err( errors::AttrApplication::StructEnumFunctionMethodUnion { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 36eee5f308656..15741ef6302c8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2004,6 +2004,8 @@ options! { "perform LLVM link-time optimizations"), metadata: Vec = (Vec::new(), parse_list, [TRACKED], "metadata to mangle symbol names with"), + min_function_alignment: Option = (None, parse_align, [TRACKED], + "align all functions to at least this many bytes. Must be a power of 2"), no_prepopulate_passes: bool = (false, parse_no_value, [TRACKED], "give an empty list of passes to the pass manager"), no_redzone: Option = (None, parse_opt_bool, [TRACKED], @@ -2309,8 +2311,6 @@ options! { "gather metadata statistics (default: no)"), metrics_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], "the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"), - min_function_alignment: Option = (None, parse_align, [TRACKED], - "align all functions to at least this many bytes. Must be a power of 2"), mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index a3b70e7f97711..8af65d57cb59b 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -331,6 +331,28 @@ opt-level=0`](#opt-level)). That is: See also [linker-plugin-lto](#linker-plugin-lto) for cross-language LTO. +## min-function-alignment + +The `-Cmin-function-alignment=` flag specifies the minimum alignment of functions for which code is generated. +The `align` value must be a power of 2, other values are rejected. + +Note that `-Zbuild-std` (or similar) is required to apply this minimum alignment to standard library functions. +By default, these functions come precompiled and their alignments won't respect the `min-function-alignment` flag. + +This flag is equivalent to: + +- `-fmin-function-alignment` for [GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmin-function-alignment_003dn) +- `-falign-functions` for [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang1-falign-functions) + +The specified alignment is a minimum. A higher alignment can be specified for specific functions by annotating the function with a `#[repr(align())]` attribute. +The attribute's value is ignored when it is lower than the value passed to `min-function-alignment`. + +There are two additional edge cases for this flag: + +- targets have a minimum alignment for functions (e.g. on x86_64 the lowest that LLVM generates is 16 bytes). + A `min-function-alignment` value lower than the target's minimum has no effect. +- the maximum alignment supported by rust (and LLVM) is `2^29`. Trying to set a higher value results in an error. + ## metadata This option allows you to control the metadata used for symbol mangling. This diff --git a/src/doc/unstable-book/src/compiler-flags/min-function-alignment.md b/src/doc/unstable-book/src/compiler-flags/min-function-alignment.md deleted file mode 100644 index b7a3aa71fc4c8..0000000000000 --- a/src/doc/unstable-book/src/compiler-flags/min-function-alignment.md +++ /dev/null @@ -1,24 +0,0 @@ -# `min-function-alignment` - -The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/82232. - ------------------------- - -The `-Zmin-function-alignment=` flag specifies the minimum alignment of functions for which code is generated. -The `align` value must be a power of 2, other values are rejected. - -Note that `-Zbuild-std` (or similar) is required to apply this minimum alignment to standard library functions. -By default, these functions come precompiled and their alignments won't respect the `min-function-alignment` flag. - -This flag is equivalent to: - -- `-fmin-function-alignment` for [GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmin-function-alignment_003dn) -- `-falign-functions` for [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang1-falign-functions) - -The specified alignment is a minimum. A higher alignment can be specified for specific functions by using the [`repr(align(...))`](https://github.com/rust-lang/rust/issues/82232) feature and annotating the function with a `#[repr(align())]` attribute. The attribute's value is ignored when it is lower than the value passed to `min-function-alignment`. - -There are two additional edge cases for this flag: - -- targets have a minimum alignment for functions (e.g. on x86_64 the lowest that LLVM generates is 16 bytes). - A `min-function-alignment` value lower than the target's minimum has no effect. -- the maximum alignment supported by rust (and LLVM) is `2^29`. Trying to set a higher value results in an error. diff --git a/src/tools/miri/tests/pass/fn_align.rs b/src/tools/miri/tests/pass/fn_align.rs index 550bb1cb4d718..63c3e3945a04d 100644 --- a/src/tools/miri/tests/pass/fn_align.rs +++ b/src/tools/miri/tests/pass/fn_align.rs @@ -1,5 +1,4 @@ -//@compile-flags: -Zmin-function-alignment=8 -#![feature(fn_align)] +//@compile-flags: -Cmin-function-alignment=8 // When a function uses `repr(align(N))`, the function address should be a multiple of `N`. @@ -16,6 +15,6 @@ fn main() { assert!((foo as usize).is_multiple_of(256)); assert!((bar as usize).is_multiple_of(16)); - // The maximum of `repr(align(N))` and `-Zmin-function-alignment=N` is used. + // The maximum of `repr(align(N))` and `-Cmin-function-alignment=N` is used. assert!((baz as usize).is_multiple_of(8)); } diff --git a/tests/assembly/naked-functions/aix.rs b/tests/assembly/naked-functions/aix.rs index 57ff0e183bed5..68d568986062c 100644 --- a/tests/assembly/naked-functions/aix.rs +++ b/tests/assembly/naked-functions/aix.rs @@ -9,7 +9,7 @@ //@[aix] needs-llvm-components: powerpc #![crate_type = "lib"] -#![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)] +#![feature(no_core, asm_experimental_arch, f128, linkage)] #![no_core] // tests that naked functions work for the `powerpc64-ibm-aix` target. diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs index 71e4d80764a3a..94112562f03c4 100644 --- a/tests/assembly/naked-functions/wasm32.rs +++ b/tests/assembly/naked-functions/wasm32.rs @@ -9,7 +9,7 @@ //@ [wasm32-wasip1] needs-llvm-components: webassembly #![crate_type = "lib"] -#![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)] +#![feature(no_core, asm_experimental_arch, f128, linkage)] #![no_core] extern crate minicore; diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index 660d8cd2bbf4f..245a09156067f 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 #![crate_type = "lib"] -#![feature(fn_align)] // CHECK: align 16 #[no_mangle] diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs index 7c0ad12402aad..e6146e9fff7b1 100644 --- a/tests/codegen/min-function-alignment.rs +++ b/tests/codegen/min-function-alignment.rs @@ -1,10 +1,9 @@ //@ revisions: align16 align1024 //@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -//@ [align16] compile-flags: -Zmin-function-alignment=16 -//@ [align1024] compile-flags: -Zmin-function-alignment=1024 +//@ [align16] compile-flags: -Cmin-function-alignment=16 +//@ [align1024] compile-flags: -Cmin-function-alignment=1024 #![crate_type = "lib"] -#![feature(fn_align)] // functions without explicit alignment use the global minimum // @@ -33,7 +32,7 @@ pub fn higher_align() {} // cold functions follow the same rules as other functions // // in GCC, the `-falign-functions` does not apply to cold functions, but -// `-Zmin-function-alignment` applies to all functions. +// `-Cmin-function-alignment` applies to all functions. // // CHECK-LABEL: @no_explicit_align_cold // align16: align 16 diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs index 47ef779f1b217..05ae6292b7e33 100644 --- a/tests/codegen/naked-fn/aligned.rs +++ b/tests/codegen/naked-fn/aligned.rs @@ -3,7 +3,6 @@ //@ ignore-arm no "ret" mnemonic #![crate_type = "lib"] -#![feature(fn_align)] use std::arch::naked_asm; // CHECK: .balign 16 diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs index 1d778be8c90dc..ba35d263df733 100644 --- a/tests/codegen/naked-fn/min-function-alignment.rs +++ b/tests/codegen/naked-fn/min-function-alignment.rs @@ -1,8 +1,7 @@ -//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16 +//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Cmin-function-alignment=16 //@ needs-asm-support //@ ignore-arm no "ret" mnemonic -#![feature(fn_align)] #![crate_type = "lib"] // functions without explicit alignment use the global minimum @@ -33,7 +32,7 @@ pub extern "C" fn naked_higher_align() { // cold functions follow the same rules as other functions // // in GCC, the `-falign-functions` does not apply to cold functions, but -// `-Zmin-function-alignment` applies to all functions. +// `-Cmin-function-alignment` applies to all functions. // // CHECK: .balign 16 #[no_mangle] diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs index 96eed70dc5504..107d88f009e12 100644 --- a/tests/ui/asm/naked-with-invalid-repr-attr.rs +++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs @@ -1,5 +1,4 @@ //@ needs-asm-support -#![feature(fn_align)] #![crate_type = "lib"] use std::arch::naked_asm; diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr index f173a39e5bf6d..fb9dea5f87a90 100644 --- a/tests/ui/asm/naked-with-invalid-repr-attr.stderr +++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr @@ -1,5 +1,5 @@ error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/naked-with-invalid-repr-attr.rs:6:8 + --> $DIR/naked-with-invalid-repr-attr.rs:5:8 | LL | #[repr(C)] | ^ @@ -11,7 +11,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/naked-with-invalid-repr-attr.rs:14:8 + --> $DIR/naked-with-invalid-repr-attr.rs:13:8 | LL | #[repr(transparent)] | ^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/naked-with-invalid-repr-attr.rs:22:19 + --> $DIR/naked-with-invalid-repr-attr.rs:21:19 | LL | #[repr(align(16), C)] | ^ @@ -35,7 +35,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/naked-with-invalid-repr-attr.rs:31:8 + --> $DIR/naked-with-invalid-repr-attr.rs:30:8 | LL | #[repr(C, packed)] | ^ @@ -48,7 +48,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct or union - --> $DIR/naked-with-invalid-repr-attr.rs:31:11 + --> $DIR/naked-with-invalid-repr-attr.rs:30:11 | LL | #[repr(C, packed)] | ^^^^^^ @@ -61,7 +61,7 @@ LL | | } | |_- not a struct or union error[E0517]: attribute should be applied to an enum - --> $DIR/naked-with-invalid-repr-attr.rs:41:8 + --> $DIR/naked-with-invalid-repr-attr.rs:40:8 | LL | #[repr(u8)] | ^^ diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index 4aaad01b7235e..d52662b637ac0 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -1,7 +1,9 @@ -#![feature(fn_align)] #![crate_type = "lib"] trait MyTrait { #[repr(align)] //~ ERROR invalid `repr(align)` attribute: `align` needs an argument - fn myfun(); + fn myfun1(); + + #[repr(align(1, 2))] //~ ERROR incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + fn myfun2(); } diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index 57913c48ef787..fb61ce98151e7 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -1,9 +1,16 @@ error[E0589]: invalid `repr(align)` attribute: `align` needs an argument - --> $DIR/malformed-fn-align.rs:5:12 + --> $DIR/malformed-fn-align.rs:4:12 | LL | #[repr(align)] | ^^^^^ help: supply an argument here: `align(...)` -error: aborting due to 1 previous error +error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + --> $DIR/malformed-fn-align.rs:7:12 + | +LL | #[repr(align(1, 2))] + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0589`. +Some errors have detailed explanations: E0589, E0693. +For more information about an error, try `rustc --explain E0589`. diff --git a/tests/ui/feature-gates/feature-gate-fn_align.rs b/tests/ui/feature-gates/feature-gate-fn_align.rs deleted file mode 100644 index 744877704dd11..0000000000000 --- a/tests/ui/feature-gates/feature-gate-fn_align.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_type = "lib"] - -#[repr(align(16))] //~ ERROR `repr(align)` attributes on functions are unstable -fn requires_alignment() {} - -trait MyTrait { - #[repr(align)] //~ ERROR invalid `repr(align)` attribute: `align` needs an argument - fn myfun(); -} diff --git a/tests/ui/feature-gates/feature-gate-fn_align.stderr b/tests/ui/feature-gates/feature-gate-fn_align.stderr deleted file mode 100644 index ff17c29fe0296..0000000000000 --- a/tests/ui/feature-gates/feature-gate-fn_align.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0589]: invalid `repr(align)` attribute: `align` needs an argument - --> $DIR/feature-gate-fn_align.rs:7:12 - | -LL | #[repr(align)] - | ^^^^^ help: supply an argument here: `align(...)` - -error[E0658]: `repr(align)` attributes on functions are unstable - --> $DIR/feature-gate-fn_align.rs:3:8 - | -LL | #[repr(align(16))] - | ^^^^^^^^^ - | - = note: see issue #82232 for more information - = help: add `#![feature(fn_align)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0589, E0658. -For more information about an error, try `rustc --explain E0589`.