Skip to content

Commit

Permalink
add ui tests for repr align on functions; also with naked present, an…
Browse files Browse the repository at this point in the history
…d update diagnostics
  • Loading branch information
jdonszelmann committed Aug 27, 2024
1 parent 3c71124 commit 87beb43
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 0 deletions.
15 changes: 15 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
-passes_see_issue =
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
-fn_align_hint =
`#[repr(align(...))]` is valid on functions
-fn_align_hint_align_present =
`#[repr(align(...))]` alone is valid on functions
passes_abi_invalid_attribute =
`#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
passes_abi_ne =
Expand All @@ -24,22 +29,32 @@ passes_allow_internal_unstable =
passes_attr_application_enum =
attribute should be applied to an enum
.label = not an enum
.align_note = {-fn_align_hint}
.align_note_present = {-fn_align_hint_align_present}
passes_attr_application_struct =
attribute should be applied to a struct
.label = not a struct
.align_note = {-fn_align_hint}
.align_note_present = {-fn_align_hint_align_present}
passes_attr_application_struct_enum_function_method_union =
attribute should be applied to a struct, enum, function, associated function, or union
.label = not a struct, enum, function, associated function, or union
.align_note = {-fn_align_hint}
.align_note_present = {-fn_align_hint_align_present}
passes_attr_application_struct_enum_union =
attribute should be applied to a struct, enum, or union
.label = not a struct, enum, or union
.align_note = {-fn_align_hint}
.align_note_present = {-fn_align_hint_align_present}
passes_attr_application_struct_union =
attribute should be applied to a struct or union
.label = not a struct or union
.align_note = {-fn_align_hint}
.align_note_present = {-fn_align_hint_align_present}
passes_attr_crate_level =
this attribute can only be applied at the crate level
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1783,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) =
match (self.tcx.features().fn_align, has_align, target) {
// fn_align is on, there's an align attribute, and the target is an fn
(true, Some(span), Target::Fn) => (false, Some(span)),
// fn_align is on, there's no align attribute, and the target is an fn
(true, None, Target::Fn) => (true, None),
_ => (false, None),
};

for hint in &hints {
if !hint.is_meta_item() {
self.dcx().emit_err(errors::ReprIdent { span: hint.span() });
Expand All @@ -1801,6 +1812,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
hint_span: hint.span(),
span,
align_note,
align_present_note,
});
}
}
Expand Down Expand Up @@ -1829,6 +1842,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
errors::AttrApplication::StructEnumFunctionMethodUnion {
hint_span: hint.span(),
span,
align_note,
align_present_note,
},
);
}
Expand All @@ -1839,6 +1854,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::AttrApplication::StructUnion {
hint_span: hint.span(),
span,
align_note,
align_present_note,
});
} else {
continue;
Expand All @@ -1850,6 +1867,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::AttrApplication::Struct {
hint_span: hint.span(),
span,
align_note,
align_present_note,
});
} else {
continue;
Expand All @@ -1863,6 +1882,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
hint_span: hint.span(),
span,
align_note,
align_present_note,
});
}
}
Expand All @@ -1884,6 +1905,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::AttrApplication::Enum {
hint_span: hint.span(),
span,
align_note,
align_present_note,
});
} else {
continue;
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,34 +1425,59 @@ pub enum AttrApplication {
hint_span: Span,
#[label]
span: Span,

#[note(passes_align_note)]
align_note: bool,
#[note(passes_align_note_present)]
align_present_note: Option<Span>,
},
#[diag(passes_attr_application_struct, code = E0517)]
Struct {
#[primary_span]
hint_span: Span,
#[label]
span: Span,

#[note(passes_align_note)]
align_note: bool,
#[note(passes_align_note_present)]
align_present_note: Option<Span>,
},
#[diag(passes_attr_application_struct_union, code = E0517)]
StructUnion {
#[primary_span]
hint_span: Span,
#[label]
span: Span,

#[note(passes_align_note)]
align_note: bool,
#[note(passes_align_note_present)]
align_present_note: Option<Span>,
},
#[diag(passes_attr_application_struct_enum_union, code = E0517)]
StructEnumUnion {
#[primary_span]
hint_span: Span,
#[label]
span: Span,

#[note(passes_align_note)]
align_note: bool,
#[note(passes_align_note_present)]
align_present_note: Option<Span>,
},
#[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
StructEnumFunctionMethodUnion {
#[primary_span]
hint_span: Span,
#[label]
span: Span,

#[note(passes_align_note)]
align_note: bool,
#[note(passes_align_note_present)]
align_present_note: Option<Span>,
},
}

Expand Down
54 changes: 54 additions & 0 deletions tests/ui/asm/naked-with-invalid-repr-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//@ needs-asm-support
#![feature(naked_functions)]
#![feature(fn_align)]
#![crate_type = "lib"]
use std::arch::asm;

#[repr(C)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
//~| NOTE `#[repr(align(...))]` is valid on functions
#[naked]
extern "C" fn example1() {
//~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) }
}

#[repr(transparent)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
//~| NOTE `#[repr(align(...))]` is valid on functions
#[naked]
extern "C" fn example2() {
//~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) }
}

#[repr(align(16), C)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
//~| NOTE `#[repr(align(...))]` alone is valid on functions
#[naked]
extern "C" fn example3() {
//~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) }
}

// note: two errors because of packed and C
#[repr(C, packed)]
//~^ ERROR attribute should be applied to a struct or union [E0517]
//~| ERROR attribute should be applied to a struct, enum, or union [E0517]
//~| NOTE `#[repr(align(...))]` is valid on functions
//~| NOTE `#[repr(align(...))]` is valid on functions
#[naked]
extern "C" fn example4() {
//~^ NOTE not a struct, enum, or union
//~| NOTE not a struct or union
unsafe { asm!("", options(noreturn)) }
}

#[repr(u8)]
//~^ ERROR attribute should be applied to an enum [E0517]
//~| NOTE `#[repr(align(...))]` is valid on functions
#[naked]
extern "C" fn example5() {
//~^ NOTE not an enum
unsafe { asm!("", options(noreturn)) }
}
93 changes: 93 additions & 0 deletions tests/ui/asm/naked-with-invalid-repr-attr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:7:8
|
LL | #[repr(C)]
| ^
...
LL | / extern "C" fn example1() {
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, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:16:8
|
LL | #[repr(transparent)]
| ^^^^^^^^^^^
...
LL | / extern "C" fn example2() {
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, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:25:19
|
LL | #[repr(align(16), C)]
| ^
...
LL | / extern "C" fn example3() {
LL | |
LL | | unsafe { asm!("", options(noreturn)) }
LL | | }
| |_- not a struct, enum, or union
|
note: `#[repr(align(...))]` alone is valid on functions
--> $DIR/naked-with-invalid-repr-attr.rs:25:8
|
LL | #[repr(align(16), C)]
| ^^^^^^^^^

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() {
LL | |
LL | |
LL | | unsafe { asm!("", options(noreturn)) }
LL | | }
| |_- not a struct or union
|
= note: `#[repr(align(...))]` is valid on functions

error[E0517]: attribute should be applied to an enum
--> $DIR/naked-with-invalid-repr-attr.rs:47:8
|
LL | #[repr(u8)]
| ^^
...
LL | / extern "C" fn example5() {
LL | |
LL | | unsafe { asm!("", options(noreturn)) }
LL | | }
| |_- not an enum
|
= note: `#[repr(align(...))]` is valid on functions

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0517`.

0 comments on commit 87beb43

Please sign in to comment.