Skip to content

Commit 3528a5b

Browse files
committed
Auto merge of #140915 - matthiaskrgr:rollup-lxce4zr, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #140397 (Add T-compiler backports Zulip notifications) - #140851 (Warn when `#[export_name]` is used with generic functions) - #140862 (Enable non-leaf Frame Pointers for Arm64EC Windows) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 16c1c54 + 4d3c472 commit 3528a5b

File tree

7 files changed

+523
-25
lines changed

7 files changed

+523
-25
lines changed

compiler/rustc_lint/src/builtin.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -976,17 +976,21 @@ declare_lint! {
976976
/// ```rust
977977
/// #[unsafe(no_mangle)]
978978
/// fn foo<T>(t: T) {}
979+
///
980+
/// #[unsafe(export_name = "bar")]
981+
/// fn bar<T>(t: T) {}
979982
/// ```
980983
///
981984
/// {{produces}}
982985
///
983986
/// ### Explanation
984987
///
985988
/// A function with generics must have its symbol mangled to accommodate
986-
/// the generic parameter. The [`no_mangle` attribute] has no effect in
987-
/// this situation, and should be removed.
989+
/// the generic parameter. The [`no_mangle`] and [`export_name`] attributes
990+
/// have no effect in this situation, and should be removed.
988991
///
989-
/// [`no_mangle` attribute]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute
992+
/// [`no_mangle`]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute
993+
/// [`export_name`]: https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute
990994
NO_MANGLE_GENERIC_ITEMS,
991995
Warn,
992996
"generic items must be mangled"
@@ -997,7 +1001,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
9971001
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
9981002
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
9991003
let attrs = cx.tcx.hir_attrs(it.hir_id());
1000-
let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute,
1004+
let check_no_mangle_on_generic_fn = |attr: &hir::Attribute,
10011005
impl_generics: Option<&hir::Generics<'_>>,
10021006
generics: &hir::Generics<'_>,
10031007
span| {
@@ -1010,7 +1014,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10101014
cx.emit_span_lint(
10111015
NO_MANGLE_GENERIC_ITEMS,
10121016
span,
1013-
BuiltinNoMangleGeneric { suggestion: no_mangle_attr.span() },
1017+
BuiltinNoMangleGeneric { suggestion: attr.span() },
10141018
);
10151019
break;
10161020
}
@@ -1019,8 +1023,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10191023
};
10201024
match it.kind {
10211025
hir::ItemKind::Fn { generics, .. } => {
1022-
if let Some(no_mangle_attr) = attr::find_by_name(attrs, sym::no_mangle) {
1023-
check_no_mangle_on_generic_fn(no_mangle_attr, None, generics, it.span);
1026+
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
1027+
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
1028+
{
1029+
check_no_mangle_on_generic_fn(attr, None, generics, it.span);
10241030
}
10251031
}
10261032
hir::ItemKind::Const(..) => {
@@ -1048,11 +1054,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10481054
hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => {
10491055
for it in *items {
10501056
if let hir::AssocItemKind::Fn { .. } = it.kind {
1051-
if let Some(no_mangle_attr) =
1052-
attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle)
1057+
let attrs = cx.tcx.hir_attrs(it.id.hir_id());
1058+
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
1059+
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
10531060
{
10541061
check_no_mangle_on_generic_fn(
1055-
no_mangle_attr,
1062+
attr,
10561063
Some(generics),
10571064
cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(),
10581065
it.span,

compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
1+
use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base};
22

33
pub(crate) fn target() -> Target {
44
let mut base = base::windows_msvc::opts();
@@ -10,6 +10,12 @@ pub(crate) fn target() -> Target {
1010
&["/machine:arm64ec", "softintrin.lib"],
1111
);
1212

13+
// Microsoft recommends enabling frame pointers on Arm64 Windows.
14+
// From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers
15+
// "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW
16+
// and other services. It must point to the previous {x29, x30} pair on the stack."
17+
base.frame_pointer = FramePointer::NonLeaf;
18+
1319
Target {
1420
llvm_target: "arm64ec-pc-windows-msvc".into(),
1521
metadata: TargetMetadata {

tests/assembly/asm/aarch64-types.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ pub unsafe fn sym_static() {
8686

8787
// Regression test for #75761
8888
// CHECK-LABEL: {{("#)?}}issue_75761{{"?}}
89-
// CHECK: str {{.*}}x30
89+
// aarch64: str {{.*}}x30
90+
// arm64ec: stp {{.*}}x30
9091
// CHECK: //APP
9192
// CHECK: //NO_APP
92-
// CHECK: ldr {{.*}}x30
93+
// aarch64: ldr {{.*}}x30
94+
// arm64ec: ldp {{.*}}x30
9395
#[no_mangle]
9496
pub unsafe fn issue_75761() {
9597
asm!("", out("v0") _, out("x30") _);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
//@ run-rustfix
2+
#![allow(dead_code, elided_named_lifetimes)]
3+
#![deny(no_mangle_generic_items)]
4+
5+
pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
6+
7+
pub extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
8+
9+
#[export_name = "baz"]
10+
pub fn baz(x: &i32) -> &i32 { x }
11+
12+
#[export_name = "qux"]
13+
pub fn qux<'a>(x: &'a i32) -> &i32 { x }
14+
15+
pub struct Foo;
16+
17+
impl Foo {
18+
19+
pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
20+
21+
22+
pub extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
23+
24+
#[export_name = "baz"]
25+
pub fn baz(x: &i32) -> &i32 { x }
26+
27+
#[export_name = "qux"]
28+
pub fn qux<'a>(x: &'a i32) -> &i32 { x }
29+
}
30+
31+
trait Trait1 {
32+
fn foo<T>();
33+
extern "C" fn bar<T>();
34+
fn baz(x: &i32) -> &i32;
35+
fn qux<'a>(x: &'a i32) -> &i32;
36+
}
37+
38+
impl Trait1 for Foo {
39+
40+
fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
41+
42+
43+
extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
44+
45+
#[export_name = "baz"]
46+
fn baz(x: &i32) -> &i32 { x }
47+
48+
#[export_name = "qux"]
49+
fn qux<'a>(x: &'a i32) -> &i32 { x }
50+
}
51+
52+
trait Trait2<T> {
53+
fn foo();
54+
fn foo2<U>();
55+
extern "C" fn bar();
56+
fn baz(x: &i32) -> &i32;
57+
fn qux<'a>(x: &'a i32) -> &i32;
58+
}
59+
60+
impl<T> Trait2<T> for Foo {
61+
62+
fn foo() {} //~ ERROR functions generic over types or consts must be mangled
63+
64+
65+
fn foo2<U>() {} //~ ERROR functions generic over types or consts must be mangled
66+
67+
68+
extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
69+
70+
71+
fn baz(x: &i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
72+
73+
74+
fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled
75+
}
76+
77+
pub struct Bar<T>(#[allow(dead_code)] T);
78+
79+
impl<T> Bar<T> {
80+
81+
pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled
82+
83+
84+
pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
85+
86+
87+
pub fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
88+
}
89+
90+
impl Bar<i32> {
91+
#[export_name = "qux"]
92+
pub fn qux() {}
93+
}
94+
95+
trait Trait3 {
96+
fn foo();
97+
extern "C" fn bar();
98+
fn baz<U>();
99+
}
100+
101+
impl<T> Trait3 for Bar<T> {
102+
103+
fn foo() {} //~ ERROR functions generic over types or consts must be mangled
104+
105+
106+
extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled
107+
108+
109+
fn baz<U>() {} //~ ERROR functions generic over types or consts must be mangled
110+
}
111+
112+
pub struct Baz<'a>(#[allow(dead_code)] &'a i32);
113+
114+
impl<'a> Baz<'a> {
115+
#[export_name = "foo"]
116+
pub fn foo() {}
117+
118+
#[export_name = "bar"]
119+
pub fn bar<'b>(x: &'b i32) -> &i32 { x }
120+
}
121+
122+
trait Trait4 {
123+
fn foo();
124+
fn bar<'a>(x: &'a i32) -> &i32;
125+
}
126+
127+
impl Trait4 for Bar<i32> {
128+
#[export_name = "foo"]
129+
fn foo() {}
130+
131+
#[export_name = "bar"]
132+
fn bar<'b>(x: &'b i32) -> &i32 { x }
133+
}
134+
135+
impl<'a> Trait4 for Baz<'a> {
136+
#[export_name = "foo"]
137+
fn foo() {}
138+
139+
#[export_name = "bar"]
140+
fn bar<'b>(x: &'b i32) -> &i32 { x }
141+
}
142+
143+
trait Trait5<T> {
144+
fn foo();
145+
}
146+
147+
impl Trait5<i32> for Foo {
148+
#[export_name = "foo"]
149+
fn foo() {}
150+
}
151+
152+
impl Trait5<i32> for Bar<i32> {
153+
#[export_name = "foo"]
154+
fn foo() {}
155+
}
156+
157+
fn main() {}

0 commit comments

Comments
 (0)