Skip to content

Commit 45f8724

Browse files
committed
add ui tests for repr align on functions; also with naked present, and update diagnostics
1 parent 3c71124 commit 45f8724

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

Diff for: compiler/rustc_passes/messages.ftl

+15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
-passes_see_issue =
55
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
66
7+
-fn_align_hint =
8+
`#[repr(align(...))]` is valid on functions
9+
-fn_align_hint_align_present =
10+
`#[repr(align(...))]` alone is valid on functions
11+
712
passes_abi_invalid_attribute =
813
`#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
914
passes_abi_ne =
@@ -24,22 +29,32 @@ passes_allow_internal_unstable =
2429
passes_attr_application_enum =
2530
attribute should be applied to an enum
2631
.label = not an enum
32+
.align_note = {-fn_align_hint}
33+
.align_note_present = {-fn_align_hint_align_present}
2734
2835
passes_attr_application_struct =
2936
attribute should be applied to a struct
3037
.label = not a struct
38+
.align_note = {-fn_align_hint}
39+
.align_note_present = {-fn_align_hint_align_present}
3140
3241
passes_attr_application_struct_enum_function_method_union =
3342
attribute should be applied to a struct, enum, function, associated function, or union
3443
.label = not a struct, enum, function, associated function, or union
44+
.align_note = {-fn_align_hint}
45+
.align_note_present = {-fn_align_hint_align_present}
3546
3647
passes_attr_application_struct_enum_union =
3748
attribute should be applied to a struct, enum, or union
3849
.label = not a struct, enum, or union
50+
.align_note = {-fn_align_hint}
51+
.align_note_present = {-fn_align_hint_align_present}
3952
4053
passes_attr_application_struct_union =
4154
attribute should be applied to a struct or union
4255
.label = not a struct or union
56+
.align_note = {-fn_align_hint}
57+
.align_note_present = {-fn_align_hint_align_present}
4358
4459
passes_attr_crate_level =
4560
this attribute can only be applied at the crate level

Diff for: compiler/rustc_passes/src/check_attr.rs

+23
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17831783
let mut is_simd = false;
17841784
let mut is_transparent = false;
17851785

1786+
let has_align =
1787+
hints.iter().find_map(|i| (i.name_or_empty() == sym::align).then(|| i.span()));
1788+
let (align_note, align_present_note) =
1789+
match (self.tcx.features().fn_align, has_align, target) {
1790+
// fn_align is on, there's an align attribute, and the target is an fn
1791+
(true, Some(span), Target::Fn) => (false, Some(span)),
1792+
// fn_align is on, there's no align attribute, and the target is an fn
1793+
(true, None, Target::Fn) => (true, None),
1794+
_ => (false, None),
1795+
};
1796+
17861797
for hint in &hints {
17871798
if !hint.is_meta_item() {
17881799
self.dcx().emit_err(errors::ReprIdent { span: hint.span() });
@@ -1801,6 +1812,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18011812
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
18021813
hint_span: hint.span(),
18031814
span,
1815+
align_note,
1816+
align_present_note,
18041817
});
18051818
}
18061819
}
@@ -1829,6 +1842,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18291842
errors::AttrApplication::StructEnumFunctionMethodUnion {
18301843
hint_span: hint.span(),
18311844
span,
1845+
align_note,
1846+
align_present_note,
18321847
},
18331848
);
18341849
}
@@ -1839,6 +1854,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18391854
self.dcx().emit_err(errors::AttrApplication::StructUnion {
18401855
hint_span: hint.span(),
18411856
span,
1857+
align_note,
1858+
align_present_note,
18421859
});
18431860
} else {
18441861
continue;
@@ -1850,6 +1867,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18501867
self.dcx().emit_err(errors::AttrApplication::Struct {
18511868
hint_span: hint.span(),
18521869
span,
1870+
align_note,
1871+
align_present_note,
18531872
});
18541873
} else {
18551874
continue;
@@ -1863,6 +1882,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18631882
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
18641883
hint_span: hint.span(),
18651884
span,
1885+
align_note,
1886+
align_present_note,
18661887
});
18671888
}
18681889
}
@@ -1884,6 +1905,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18841905
self.dcx().emit_err(errors::AttrApplication::Enum {
18851906
hint_span: hint.span(),
18861907
span,
1908+
align_note,
1909+
align_present_note,
18871910
});
18881911
} else {
18891912
continue;

Diff for: compiler/rustc_passes/src/errors.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1425,34 +1425,59 @@ pub enum AttrApplication {
14251425
hint_span: Span,
14261426
#[label]
14271427
span: Span,
1428+
1429+
#[note(passes_align_note)]
1430+
align_note: bool,
1431+
#[note(passes_align_note_present)]
1432+
align_present_note: Option<Span>,
14281433
},
14291434
#[diag(passes_attr_application_struct, code = E0517)]
14301435
Struct {
14311436
#[primary_span]
14321437
hint_span: Span,
14331438
#[label]
14341439
span: Span,
1440+
1441+
#[note(passes_align_note)]
1442+
align_note: bool,
1443+
#[note(passes_align_note_present)]
1444+
align_present_note: Option<Span>,
14351445
},
14361446
#[diag(passes_attr_application_struct_union, code = E0517)]
14371447
StructUnion {
14381448
#[primary_span]
14391449
hint_span: Span,
14401450
#[label]
14411451
span: Span,
1452+
1453+
#[note(passes_align_note)]
1454+
align_note: bool,
1455+
#[note(passes_align_note_present)]
1456+
align_present_note: Option<Span>,
14421457
},
14431458
#[diag(passes_attr_application_struct_enum_union, code = E0517)]
14441459
StructEnumUnion {
14451460
#[primary_span]
14461461
hint_span: Span,
14471462
#[label]
14481463
span: Span,
1464+
1465+
#[note(passes_align_note)]
1466+
align_note: bool,
1467+
#[note(passes_align_note_present)]
1468+
align_present_note: Option<Span>,
14491469
},
14501470
#[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
14511471
StructEnumFunctionMethodUnion {
14521472
#[primary_span]
14531473
hint_span: Span,
14541474
#[label]
14551475
span: Span,
1476+
1477+
#[note(passes_align_note)]
1478+
align_note: bool,
1479+
#[note(passes_align_note_present)]
1480+
align_present_note: Option<Span>,
14561481
},
14571482
}
14581483

Diff for: tests/ui/asm/naked-with-invalid-repr-attr.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//@ needs-asm-support
2+
#![feature(naked_functions)]
3+
#![feature(fn_align)]
4+
#![crate_type = "lib"]
5+
use std::arch::asm;
6+
7+
#[repr(C)]
8+
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
9+
//~| NOTE `#[repr(align(...))]` is valid on functions
10+
#[naked]
11+
extern "C" fn example1() {
12+
//~^ NOTE not a struct, enum, or union
13+
unsafe { asm!("", options(noreturn)) }
14+
}
15+
16+
#[repr(transparent)]
17+
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
18+
//~| NOTE `#[repr(align(...))]` is valid on functions
19+
#[naked]
20+
extern "C" fn example2() {
21+
//~^ NOTE not a struct, enum, or union
22+
unsafe { asm!("", options(noreturn)) }
23+
}
24+
25+
#[repr(align(16), C)]
26+
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
27+
//~| NOTE `#[repr(align(...))]` alone is valid on functions
28+
#[naked]
29+
extern "C" fn example3() {
30+
//~^ NOTE not a struct, enum, or union
31+
unsafe { asm!("", options(noreturn)) }
32+
}
33+
34+
// note: two errors because of packed and C
35+
#[repr(C, packed)]
36+
//~^ ERROR attribute should be applied to a struct or union [E0517]
37+
//~| ERROR attribute should be applied to a struct, enum, or union [E0517]
38+
//~| NOTE `#[repr(align(...))]` is valid on functions
39+
//~| NOTE `#[repr(align(...))]` is valid on functions
40+
#[naked]
41+
extern "C" fn example4() {
42+
//~^ NOTE not a struct, enum, or union
43+
//~| NOTE not a struct or union
44+
unsafe { asm!("", options(noreturn)) }
45+
}
46+
47+
#[repr(u8)]
48+
//~^ ERROR attribute should be applied to an enum [E0517]
49+
//~| NOTE `#[repr(align(...))]` is valid on functions
50+
#[naked]
51+
extern "C" fn example5() {
52+
//~^ NOTE not an enum
53+
unsafe { asm!("", options(noreturn)) }
54+
}

0 commit comments

Comments
 (0)