-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add repr to the allowlist for naked functions #129421
add repr to the allowlist for naked functions #129421
Conversation
r? @wesleywiser rustbot has assigned @wesleywiser. Use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found these two tests for the combinations of #[repr]
, #[naked]
, and things that accept one or the other:
rust/tests/ui/asm/naked-invalid-attr.rs
Lines 14 to 19 in f167efa
#[naked] //~ ERROR should be applied to a function definition #[repr(C)] struct S { a: u32, b: u32, } #[repr(C)] fn f() { }
However, I wasn't able to find a UI test that checked the #[repr(C)] #[naked] fn
, or perhaps something even sillier like #[repr(transparent)] #[naked] fn
. I know it might be redundant, but I would prefer we did have a test to validate that specifically.
If it truly doesn't seem to be worth it then the fixes to the directives would be enough.
tests/codegen/naked-fn/aligned.rs
Outdated
@@ -0,0 +1,20 @@ | |||
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 | |||
//@ needs-asm-support | |||
//@ only-x86_64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this is x86_64 only? I believe ret
should also be a valid instruction on:
- x86
- aarch64
- avr
- msp430
- riscv32
- riscv64
- sparc
- sparc64
- xtensa
...it's true that AArch32, LoongArch, MIPS, Power ISA (AKA "PowerPC"), and Z/Architecture have chosen to be more... orthogonal (or just peculiar in the last case).
But it would be nice to see this test work on all of the ones that would support it without modification, and since the inclusions will be longer than the number of exclusions, we should probably reverse it. And of the exclusions, only one qualifies with needs-asm-support
:
//@ only-x86_64 | |
//@ ignore-arm no "ret" mnemonic |
People maintaining the other ISA may wish to fix this test in a manner other than ignoring it when they turn on needs-asm-support
, so we can simply let them do so.
#![feature(naked_functions, fn_align)] | ||
use std::arch::asm; | ||
|
||
// CHECK: Function Attrs: naked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is just checking a comment but that's probably fine since the check that validates the attribute is actually attached to the function is more annoying to write and LLVM doesn't emit these comments for no reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is similar to how the tests for naked functions itself work. It may not be perfect but at least it's consistent as-is
tests/codegen/naked-fn/aligned.rs
Outdated
#[no_mangle] | ||
#[naked] | ||
pub unsafe extern "C" fn naked_empty() { | ||
// CHECK-NEXT: {{.+}}: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's always going to be this label:
// CHECK-NEXT: {{.+}}: | |
// CHECK-NEXT: start: |
fair comments, especially the one on isa support. The test was made by merging an existing test for |
45f8724
to
87beb43
Compare
@rustbot ready @workingjubilee Note that I also changed a few diagnostics to make it hint at the right label :) |
LL | | } | ||
| |_- not a struct, enum, or union | ||
| | ||
= note: `#[repr(align(...))]` is valid on functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we noting this? It's extraneous -- I put repr(C)
on an extern block; that has nothing to do with repr(align)
or functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er, misread that as an extern block. I would still probably rather not note this at all, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extern "C" fn example1() {
isn't an extern block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't an extern block, it's a function. It wouldn't trigger if it wasn't a function. My reasoning was that the only valid repr on functions is align, so if you put repr(C) there you might like to know that align is a valid repr, but the one you used is not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er, misread that as an extern block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very silly language.
error[E0517]: attribute should be applied to a struct, enum, or union | ||
--> $DIR/naked-with-invalid-repr-attr.rs:35:8 | ||
| | ||
LL | #[repr(C, packed)] | ||
| ^ | ||
... | ||
LL | / extern "C" fn example4() { | ||
LL | | | ||
LL | | | ||
LL | | unsafe { asm!("", options(noreturn)) } | ||
LL | | } | ||
| |_- not a struct, enum, or union | ||
| | ||
= note: `#[repr(align(...))]` is valid on functions | ||
|
||
error[E0517]: attribute should be applied to a struct or union | ||
--> $DIR/naked-with-invalid-repr-attr.rs:35:11 | ||
| | ||
LL | #[repr(C, packed)] | ||
| ^^^^^^ | ||
... | ||
LL | / extern "C" fn example4() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to only emit 1 diagnostic for multiple errors on the same fn at least?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's existing behavior of the repr
attribute, got nothing to do with naked nor repr(align)
, but I agree it's not very nice. I can open a separate PR for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
@@ -1782,6 +1783,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | |||
let mut is_simd = false; | |||
let mut is_transparent = false; | |||
|
|||
let has_align = | |||
hints.iter().find_map(|i| (i.name_or_empty() == sym::align).then(|| i.span())); | |||
let (align_note, align_present_note) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
align_present_note
and align_note
are mutually exclusive, and both are only conditional on self.tcx.features().fn_align
. I'd prefer if you represent this with an:
#[derive(Subdiagnostic)]
enum FnAlignSuggestion {
#[note(passes_align_present_note)]
OnlyAlign,
#[note(passes_align_note)]
SupportsAlign,
}
And then using Option<FnAlignSuggestion>
. This avoid needing to add two fields to every diagnostic, and needing to repeat the note several times in the fluent grammar.
This is kinda unrelated to your change here, though -- I'd somewhat rather you break this into a separate PR so we can refine it separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea that's reasonable, just a moment :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks now I also understand properly how to use subdiagnostics like this :)
One last thing -- the second and fourth commits should be squashed into the first IMO. |
59a53eb
to
dfd90d0
Compare
dfd90d0
to
a507ec6
Compare
( tests are implied. ) |
( yes, this is stated with a long, meaningful gaze at people whomst do not add tests. ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! I'm happy with this if errs is happy.
@bors r=workingjubilee,compiler-errors feel free to assign me any diagnostics tweak prs as follow-up |
@bors rollup |
…iaskrgr Rollup of 11 pull requests Successful merges: - rust-lang#129421 (add repr to the allowlist for naked functions) - rust-lang#129480 (docs: correct panic conditions for rem_euclid and similar functions) - rust-lang#129551 (ub_checks intrinsics: fall back to cfg(ub_checks)) - rust-lang#129608 (const-eval: do not make UbChecks behavior depend on current crate's flags) - rust-lang#129613 (interpret: do not make const-eval query result depend on tcx.sess) - rust-lang#129641 (rustdoc: fix missing resource suffix on `crates.js`) - rust-lang#129657 (Rename `BikeshedIntrinsicFrom` to `TransmuteFrom`) - rust-lang#129666 (interpret: add missing alignment check in raw_eq) - rust-lang#129667 (Rustc driver cleanup) - rust-lang#129668 (Fix Pin::set bounds regression) - rust-lang#129686 (coverage: Rename `CodeRegion` to `SourceRegion`) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 11 pull requests Successful merges: - rust-lang#129421 (add repr to the allowlist for naked functions) - rust-lang#129480 (docs: correct panic conditions for rem_euclid and similar functions) - rust-lang#129551 (ub_checks intrinsics: fall back to cfg(ub_checks)) - rust-lang#129608 (const-eval: do not make UbChecks behavior depend on current crate's flags) - rust-lang#129613 (interpret: do not make const-eval query result depend on tcx.sess) - rust-lang#129641 (rustdoc: fix missing resource suffix on `crates.js`) - rust-lang#129657 (Rename `BikeshedIntrinsicFrom` to `TransmuteFrom`) - rust-lang#129666 (interpret: add missing alignment check in raw_eq) - rust-lang#129667 (Rustc driver cleanup) - rust-lang#129668 (Fix Pin::set bounds regression) - rust-lang#129686 (coverage: Rename `CodeRegion` to `SourceRegion`) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#129421 - jdonszelmann:naked-repr-align-functions, r=workingjubilee,compiler-errors add repr to the allowlist for naked functions Fixes rust-lang#129412 (combining unstable features rust-lang#90957 (`#![feature(naked_functions)]`) and rust-lang#82232 (`#![feature(fn_align)]`)
Fixes #129412 (combining unstable features #90957 (
#![feature(naked_functions)]
) and #82232 (#![feature(fn_align)]
)