Skip to content

Commit 70f6778

Browse files
authored
Unrolled build for rust-lang#128784
Rollup merge of rust-lang#128784 - tdittr:check-abi-on-fn-ptr, r=compiler-errors Check ABI target compatibility for function pointers Tracking issue: rust-lang#130260 Related tracking issue: rust-lang#87678 Compatibility of an ABI for a target was previously only performed on function definitions and `extern` blocks. This PR adds it also to function pointers to be consistent. This might have broken some of the `tests/ui/` depending on the platform, so a try run seems like a good idea. Also this might break existing code, because we now emit extra errors. Does this require a crater run? # Example ```rust // build with: --target=x86_64-unknown-linux-gnu // These raise E0570 extern "thiscall" fn foo() {} extern "thiscall" { fn bar() } // This did not raise any error fn baz(f: extern "thiscall" fn()) { f() } ``` # Open Questions * [x] Should this report a future incompatibility warning like rust-lang#87678 ? * [ ] Is this the best place to perform the check?
2 parents 6b9676b + 867e776 commit 70f6778

20 files changed

+1128
-82
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use rustc_hir::Node;
88
use rustc_hir::def::{CtorKind, DefKind};
99
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1010
use rustc_infer::traits::Obligation;
11-
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
11+
use rustc_lint_defs::builtin::{
12+
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
13+
};
1214
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
1315
use rustc_middle::middle::stability::EvalResult;
1416
use rustc_middle::span_bug;
@@ -52,16 +54,18 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
5254
});
5355
}
5456
}
57+
}
5558

56-
// This ABI is only allowed on function pointers
57-
if abi == Abi::CCmseNonSecureCall {
58-
struct_span_code_err!(
59-
tcx.dcx(),
60-
span,
61-
E0781,
62-
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
63-
)
64-
.emit();
59+
pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
60+
match tcx.sess.target.is_abi_supported(abi) {
61+
Some(true) => (),
62+
Some(false) | None => {
63+
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
64+
lint.primary_message(
65+
"use of calling convention not supported on this target on function pointer",
66+
);
67+
});
68+
}
6569
}
6670
}
6771

compiler/rustc_hir_analysis/src/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub mod wfcheck;
7373

7474
use std::num::NonZero;
7575

76-
pub use check::check_abi;
76+
pub use check::{check_abi, check_abi_fn_ptr};
7777
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
7878
use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};
7979
use rustc_hir::def_id::{DefId, LocalDefId};

compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use rustc_errors::DiagCtxtHandle;
2-
use rustc_hir as hir;
3-
use rustc_hir::HirId;
1+
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
2+
use rustc_hir::{self as hir, HirId};
43
use rustc_middle::ty::layout::LayoutError;
54
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
65
use rustc_span::Span;
@@ -26,7 +25,19 @@ pub(crate) fn validate_cmse_abi<'tcx>(
2625
..
2726
}) = hir_node
2827
else {
29-
// might happen when this ABI is used incorrectly. That will be handled elsewhere
28+
let span = match tcx.parent_hir_node(hir_id) {
29+
hir::Node::Item(hir::Item {
30+
kind: hir::ItemKind::ForeignMod { .. }, span, ..
31+
}) => *span,
32+
_ => tcx.hir().span(hir_id),
33+
};
34+
struct_span_code_err!(
35+
tcx.dcx(),
36+
span,
37+
E0781,
38+
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
39+
)
40+
.emit();
3041
return;
3142
};
3243

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
5353
use tracing::{debug, debug_span, instrument};
5454

5555
use crate::bounds::Bounds;
56+
use crate::check::check_abi_fn_ptr;
5657
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
5758
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
5859
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
@@ -2337,6 +2338,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23372338
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
23382339
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
23392340

2341+
if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2342+
tcx.hir_node(hir_id)
2343+
{
2344+
check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2345+
}
2346+
23402347
// reject function types that violate cmse ABI requirements
23412348
cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
23422349

compiler/rustc_lint_defs/src/builtin.rs

+45
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ declare_lint_pass! {
124124
UNSTABLE_NAME_COLLISIONS,
125125
UNSTABLE_SYNTAX_PRE_EXPANSION,
126126
UNSUPPORTED_CALLING_CONVENTIONS,
127+
UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
127128
UNUSED_ASSIGNMENTS,
128129
UNUSED_ASSOCIATED_TYPE_BOUNDS,
129130
UNUSED_ATTRIBUTES,
@@ -3839,6 +3840,50 @@ declare_lint! {
38393840
};
38403841
}
38413842

3843+
declare_lint! {
3844+
/// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
3845+
/// a target dependent calling convention on a target that does not support this calling
3846+
/// convention on a function pointer.
3847+
///
3848+
/// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3849+
/// code, because this calling convention was never specified for those targets.
3850+
///
3851+
/// ### Example
3852+
///
3853+
/// ```rust,ignore (needs specific targets)
3854+
/// fn stdcall_ptr(f: extern "stdcall" fn ()) {
3855+
/// f()
3856+
/// }
3857+
/// ```
3858+
///
3859+
/// This will produce:
3860+
///
3861+
/// ```text
3862+
/// warning: use of calling convention not supported on this target on function pointer
3863+
/// --> $DIR/unsupported.rs:34:15
3864+
/// |
3865+
/// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
3866+
/// | ^^^^^^^^^^^^^^^^^^^^^^^^
3867+
/// |
3868+
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3869+
/// = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
3870+
/// = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
3871+
/// ```
3872+
///
3873+
/// ### Explanation
3874+
///
3875+
/// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3876+
/// defined at all, but was previously accepted due to a bug in the implementation of the
3877+
/// compiler.
3878+
pub UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
3879+
Warn,
3880+
"use of unsupported calling convention for function pointer",
3881+
@future_incompatible = FutureIncompatibleInfo {
3882+
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
3883+
reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
3884+
};
3885+
}
3886+
38423887
declare_lint! {
38433888
/// The `break_with_label_and_loop` lint detects labeled `break` expressions with
38443889
/// an unlabeled loop as their value expression.

tests/debuginfo/type-names.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// gdb-check:type = type_names::GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
1818

1919
// gdb-command:whatis generic_struct2
20-
// gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
20+
// gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "system" fn(isize) -> usize>
2121

2222
// gdb-command:whatis mod_struct
2323
// gdb-check:type = type_names::mod1::Struct2
@@ -372,7 +372,7 @@ fn main() {
372372
let simple_struct = Struct1;
373373
let generic_struct1: GenericStruct<mod1::Struct2, mod1::mod2::Struct3> =
374374
GenericStruct(PhantomData);
375-
let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
375+
let generic_struct2: GenericStruct<Struct1, extern "system" fn(isize) -> usize> =
376376
GenericStruct(PhantomData);
377377
let mod_struct = mod1::Struct2;
378378

+164-10
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,209 @@
1+
warning: use of calling convention not supported on this target on function pointer
2+
--> $DIR/unsupported.rs:35:15
3+
|
4+
LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
9+
= note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
10+
111
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
2-
--> $DIR/unsupported.rs:28:1
12+
--> $DIR/unsupported.rs:40:1
13+
|
14+
LL | extern "ptx-kernel" {}
15+
| ^^^^^^^^^^^^^^^^^^^^^^
16+
17+
warning: use of calling convention not supported on this target on function pointer
18+
--> $DIR/unsupported.rs:49:17
19+
|
20+
LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
21+
| ^^^^^^^^^^^^^^^^^^^
22+
|
23+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
24+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
25+
26+
error[E0570]: `"aapcs"` is not a supported ABI for the current target
27+
--> $DIR/unsupported.rs:62:1
28+
|
29+
LL | extern "aapcs" {}
30+
| ^^^^^^^^^^^^^^^^^
31+
32+
warning: use of calling convention not supported on this target on function pointer
33+
--> $DIR/unsupported.rs:71:18
34+
|
35+
LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
|
38+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
39+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
40+
41+
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
42+
--> $DIR/unsupported.rs:76:1
43+
|
44+
LL | extern "msp430-interrupt" {}
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46+
47+
warning: use of calling convention not supported on this target on function pointer
48+
--> $DIR/unsupported.rs:81:15
49+
|
50+
LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
51+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
52+
|
53+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
54+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
55+
56+
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
57+
--> $DIR/unsupported.rs:86:1
58+
|
59+
LL | extern "avr-interrupt" {}
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
61+
62+
warning: use of calling convention not supported on this target on function pointer
63+
--> $DIR/unsupported.rs:94:17
64+
|
65+
LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
66+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67+
|
68+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
69+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
70+
71+
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
72+
--> $DIR/unsupported.rs:105:1
73+
|
74+
LL | extern "riscv-interrupt-m" {}
75+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76+
77+
warning: use of calling convention not supported on this target on function pointer
78+
--> $DIR/unsupported.rs:116:15
79+
|
80+
LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
81+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
82+
|
83+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
84+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
85+
86+
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
87+
--> $DIR/unsupported.rs:127:1
88+
|
89+
LL | extern "x86-interrupt" {}
90+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
91+
92+
warning: use of calling convention not supported on this target on function pointer
93+
--> $DIR/unsupported.rs:139:20
94+
|
95+
LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
96+
| ^^^^^^^^^^^^^^^^^^^^^^
97+
|
98+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
100+
101+
error[E0570]: `"thiscall"` is not a supported ABI for the current target
102+
--> $DIR/unsupported.rs:152:1
103+
|
104+
LL | extern "thiscall" {}
105+
| ^^^^^^^^^^^^^^^^^^^^
106+
107+
warning: use of calling convention not supported on this target on function pointer
108+
--> $DIR/unsupported.rs:170:19
109+
|
110+
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
111+
| ^^^^^^^^^^^^^^^^^^^^^
112+
|
113+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
114+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
115+
116+
warning: use of calling convention not supported on this target
117+
--> $DIR/unsupported.rs:183:1
118+
|
119+
LL | extern "stdcall" {}
120+
| ^^^^^^^^^^^^^^^^^^^
121+
|
122+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
123+
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
124+
= note: `#[warn(unsupported_calling_conventions)]` on by default
125+
126+
warning: use of calling convention not supported on this target on function pointer
127+
--> $DIR/unsupported.rs:195:21
128+
|
129+
LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
130+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
131+
|
132+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
133+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
134+
135+
warning: use of calling convention not supported on this target on function pointer
136+
--> $DIR/unsupported.rs:203:22
137+
|
138+
LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
139+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
140+
|
141+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
142+
= note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
143+
144+
error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
145+
--> $DIR/unsupported.rs:208:1
146+
|
147+
LL | extern "C-cmse-nonsecure-entry" {}
148+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149+
150+
error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
151+
--> $DIR/unsupported.rs:33:1
3152
|
4153
LL | extern "ptx-kernel" fn ptx() {}
5154
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6155

7156
error[E0570]: `"aapcs"` is not a supported ABI for the current target
8-
--> $DIR/unsupported.rs:30:1
157+
--> $DIR/unsupported.rs:43:1
9158
|
10159
LL | extern "aapcs" fn aapcs() {}
11160
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12161

13162
error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
14-
--> $DIR/unsupported.rs:36:1
163+
--> $DIR/unsupported.rs:69:1
15164
|
16165
LL | extern "msp430-interrupt" fn msp430() {}
17166
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18167

19168
error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
20-
--> $DIR/unsupported.rs:38:1
169+
--> $DIR/unsupported.rs:79:1
21170
|
22171
LL | extern "avr-interrupt" fn avr() {}
23172
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24173

25174
error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
26-
--> $DIR/unsupported.rs:40:1
175+
--> $DIR/unsupported.rs:89:1
27176
|
28177
LL | extern "riscv-interrupt-m" fn riscv() {}
29178
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30179

31180
error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
32-
--> $DIR/unsupported.rs:45:1
181+
--> $DIR/unsupported.rs:111:1
33182
|
34183
LL | extern "x86-interrupt" fn x86() {}
35184
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36185

37186
error[E0570]: `"thiscall"` is not a supported ABI for the current target
38-
--> $DIR/unsupported.rs:50:1
187+
--> $DIR/unsupported.rs:133:1
39188
|
40189
LL | extern "thiscall" fn thiscall() {}
41190
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42191

43192
warning: use of calling convention not supported on this target
44-
--> $DIR/unsupported.rs:56:1
193+
--> $DIR/unsupported.rs:159:1
45194
|
46195
LL | extern "stdcall" fn stdcall() {}
47196
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48197
|
49198
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
50199
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
51-
= note: `#[warn(unsupported_calling_conventions)]` on by default
52200

53-
error: aborting due to 7 previous errors; 1 warning emitted
201+
error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
202+
--> $DIR/unsupported.rs:201:1
203+
|
204+
LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
205+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
206+
207+
error: aborting due to 16 previous errors; 12 warnings emitted
54208

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

0 commit comments

Comments
 (0)