Skip to content

Commit 2579d41

Browse files
committed
add (back) unsupported_calling_conventions lint to reject more invalid calling conventions
1 parent 792fc2b commit 2579d41

File tree

19 files changed

+1199
-245
lines changed

19 files changed

+1199
-245
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3786,6 +3786,7 @@ dependencies = [
37863786
"rustc_middle",
37873787
"rustc_session",
37883788
"rustc_span",
3789+
"rustc_target",
37893790
"rustc_trait_selection",
37903791
"smallvec",
37913792
"tracing",

compiler/rustc_hir_analysis/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ rustc_macros = { path = "../rustc_macros" }
2626
rustc_middle = { path = "../rustc_middle" }
2727
rustc_session = { path = "../rustc_session" }
2828
rustc_span = { path = "../rustc_span" }
29+
rustc_target = { path = "../rustc_target" }
2930
rustc_trait_selection = { path = "../rustc_trait_selection" }
3031
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
3132
tracing = "0.1"

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use rustc_hir::{LangItem, Node, intravisit};
1111
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1212
use rustc_infer::traits::{Obligation, ObligationCauseCode};
1313
use rustc_lint_defs::builtin::{
14-
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
14+
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS,
15+
UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
1516
};
1617
use rustc_middle::hir::nested_filter;
1718
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
@@ -24,6 +25,7 @@ use rustc_middle::ty::{
2425
TypeVisitable, TypeVisitableExt, fold_regions,
2526
};
2627
use rustc_session::lint::builtin::UNINHABITED_STATIC;
28+
use rustc_target::spec::{AbiMap, AbiMapping};
2729
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2830
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
2931
use rustc_trait_selection::traits;
@@ -35,25 +37,38 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
3537
use super::compare_impl_item::check_type_bounds;
3638
use super::*;
3739

38-
pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
39-
if !tcx.sess.target.is_abi_supported(abi) {
40-
struct_span_code_err!(
41-
tcx.dcx(),
42-
span,
43-
E0570,
44-
"`{abi}` is not a supported ABI for the current target",
45-
)
46-
.emit();
40+
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
41+
match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) {
42+
AbiMapping::Direct(..) => (),
43+
AbiMapping::Invalid => {
44+
struct_span_code_err!(
45+
tcx.dcx(),
46+
span,
47+
E0570,
48+
"`{abi}` is not a supported ABI for the current target",
49+
)
50+
.emit();
51+
}
52+
AbiMapping::Deprecated(..) => {
53+
tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
54+
lint.primary_message("use of calling convention not supported on this target");
55+
});
56+
}
4757
}
4858
}
4959

5060
pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
51-
if !tcx.sess.target.is_abi_supported(abi) {
52-
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
53-
lint.primary_message(format!(
54-
"the calling convention {abi} is not supported on this target"
55-
));
56-
});
61+
// This is always an FCW, even for `AbiMapping::Invalid`, since we started linting later than
62+
// in `check_abi` above.
63+
match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) {
64+
AbiMapping::Direct(..) => (),
65+
AbiMapping::Deprecated(..) | AbiMapping::Invalid => {
66+
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
67+
lint.primary_message(format!(
68+
"the calling convention {abi} is not supported on this target"
69+
));
70+
});
71+
}
5772
}
5873
}
5974

@@ -779,7 +794,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
779794
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
780795
return;
781796
};
782-
check_abi(tcx, it.span, abi);
797+
check_abi(tcx, it.hir_id(), it.span, abi);
783798

784799
for item in items {
785800
let def_id = item.id.owner_id.def_id;

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn typeck_with_inspect<'tcx>(
149149
tcx.fn_sig(def_id).instantiate_identity()
150150
};
151151

152-
check_abi(tcx, span, fn_sig.abi());
152+
check_abi(tcx, id, span, fn_sig.abi());
153153

154154
// Compute the function signature from point of view of inside the fn.
155155
let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);

compiler/rustc_lint/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ fn register_builtins(store: &mut LintStore) {
595595
"converted into hard error, see PR #125380 \
596596
<https://github.com/rust-lang/rust/pull/125380> for more information",
597597
);
598-
store.register_removed("unsupported_calling_conventions", "converted into hard error");
599598
store.register_removed(
600599
"cenum_impl_drop_cast",
601600
"converted into hard error, \

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,6 +3654,54 @@ declare_lint! {
36543654
crate_level_only
36553655
}
36563656

3657+
declare_lint! {
3658+
/// The `unsupported_calling_conventions` lint is output whenever there is a use of the
3659+
/// `stdcall`, `fastcall`, and `cdecl` calling conventions (or their unwind
3660+
/// variants) on targets that cannot meaningfully be supported for the requested target.
3661+
///
3662+
/// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3663+
/// code, because this calling convention was never specified for those targets.
3664+
///
3665+
/// Historically MSVC toolchains have fallen back to the regular C calling convention for
3666+
/// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
3667+
/// hack across many more targets.
3668+
///
3669+
/// ### Example
3670+
///
3671+
/// ```rust,ignore (needs specific targets)
3672+
/// extern "stdcall" fn stdcall() {}
3673+
/// ```
3674+
///
3675+
/// This will produce:
3676+
///
3677+
/// ```text
3678+
/// warning: use of calling convention not supported on this target
3679+
/// --> $DIR/unsupported.rs:39:1
3680+
/// |
3681+
/// LL | extern "stdcall" fn stdcall() {}
3682+
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3683+
/// |
3684+
/// = note: `#[warn(unsupported_calling_conventions)]` on by default
3685+
/// = warning: this was previously accepted by the compiler but is being phased out;
3686+
/// it will become a hard error in a future release!
3687+
/// = note: for more information, see issue ...
3688+
/// ```
3689+
///
3690+
/// ### Explanation
3691+
///
3692+
/// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3693+
/// defined at all, but was previously accepted due to a bug in the implementation of the
3694+
/// compiler.
3695+
pub UNSUPPORTED_CALLING_CONVENTIONS,
3696+
Warn,
3697+
"use of unsupported calling convention",
3698+
@future_incompatible = FutureIncompatibleInfo {
3699+
reason: FutureIncompatibilityReason::FutureReleaseError,
3700+
report_in_deps: true,
3701+
reference: "issue #137018 <https://github.com/rust-lang/rust/issues/137018>",
3702+
};
3703+
}
3704+
36573705
declare_lint! {
36583706
/// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
36593707
/// a target dependent calling convention on a target that does not support this calling

compiler/rustc_target/src/spec/abi_map.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ impl AbiMap {
115115
(ExternAbi::Vectorcall { .. }, Arch::X86 | Arch::X86_64) => {
116116
CanonAbi::X86(X86Call::Vectorcall)
117117
}
118-
(ExternAbi::Vectorcall { .. }, _) if os == OsKind::Windows => {
119-
return AbiMapping::Deprecated(CanonAbi::C);
120-
}
121118
(ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid,
122119

123120
(ExternAbi::SysV64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::SysV64),

compiler/rustc_target/src/spec/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ mod abi_map;
6262
mod base;
6363
mod json;
6464

65-
pub use abi_map::AbiMap;
65+
pub use abi_map::{AbiMap, AbiMapping};
6666
pub use base::apple;
6767
pub use base::avr::ef_avr_arch;
6868

0 commit comments

Comments
 (0)