Skip to content

Commit

Permalink
make unsupported_calling_conventions a hard error
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Sep 9, 2024
1 parent 7b18b3e commit cee68d8
Show file tree
Hide file tree
Showing 13 changed files with 42 additions and 123 deletions.
30 changes: 11 additions & 19 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc_middle::ty::{
AdtDef, GenericArgKind, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt,
};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_session::lint::builtin::UNINHABITED_STATIC;
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
Expand All @@ -34,23 +34,15 @@ use super::compare_impl_item::{check_type_bounds, compare_impl_method, compare_i
use super::*;
use crate::check::intrinsicck::InlineAsmCtxt;

pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
match tcx.sess.target.is_abi_supported(abi) {
Some(true) => (),
Some(false) => {
struct_span_code_err!(
tcx.dcx(),
span,
E0570,
"`{abi}` is not a supported ABI for the current target",
)
.emit();
}
None => {
tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
lint.primary_message("use of calling convention not supported on this target");
});
}
pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
if !tcx.sess.target.is_abi_supported(abi) {
struct_span_code_err!(
tcx.dcx(),
span,
E0570,
"`{abi}` is not a supported ABI for the current target",
)
.emit();
}

// This ABI is only allowed on function pointers
Expand Down Expand Up @@ -754,7 +746,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
return;
};
check_abi(tcx, it.hir_id(), it.span, abi);
check_abi(tcx, it.span, abi);

match abi {
Abi::RustIntrinsic => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ fn typeck_with_fallback<'tcx>(
tcx.fn_sig(def_id).instantiate_identity()
};

check_abi(tcx, id, span, fn_sig.abi());
check_abi(tcx, span, fn_sig.abi());

// Compute the function signature from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ fn register_builtins(store: &mut LintStore) {
<https://github.com/rust-lang/rust/issues/107457> for more information",
);
store.register_removed("writes_through_immutable_pointer", "converted into hard error");
store.register_removed("unsupported_calling_conventions", "converted into hard error");
}

fn register_internals(store: &mut LintStore) {
Expand Down
48 changes: 0 additions & 48 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ declare_lint_pass! {
UNSAFE_OP_IN_UNSAFE_FN,
UNSTABLE_NAME_COLLISIONS,
UNSTABLE_SYNTAX_PRE_EXPANSION,
UNSUPPORTED_CALLING_CONVENTIONS,
UNUSED_ASSIGNMENTS,
UNUSED_ASSOCIATED_TYPE_BOUNDS,
UNUSED_ATTRIBUTES,
Expand Down Expand Up @@ -3924,53 +3923,6 @@ declare_lint! {
crate_level_only
}

declare_lint! {
/// The `unsupported_calling_conventions` lint is output whenever there is a use of the
/// `stdcall`, `fastcall`, `thiscall`, `vectorcall` calling conventions (or their unwind
/// variants) on targets that cannot meaningfully be supported for the requested target.
///
/// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
/// code, because this calling convention was never specified for those targets.
///
/// Historically MSVC toolchains have fallen back to the regular C calling convention for
/// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
/// hack across many more targets.
///
/// ### Example
///
/// ```rust,ignore (needs specific targets)
/// extern "stdcall" fn stdcall() {}
/// ```
///
/// This will produce:
///
/// ```text
/// warning: use of calling convention not supported on this target
/// --> $DIR/unsupported.rs:39:1
/// |
/// LL | extern "stdcall" fn stdcall() {}
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// |
/// = note: `#[warn(unsupported_calling_conventions)]` on by default
/// = warning: this was previously accepted by the compiler but is being phased out;
/// it will become a hard error in a future release!
/// = note: for more information, see issue ...
/// ```
///
/// ### Explanation
///
/// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
/// defined at all, but was previously accepted due to a bug in the implementation of the
/// compiler.
pub UNSUPPORTED_CALLING_CONVENTIONS,
Warn,
"use of unsupported calling convention",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
reference: "issue #87678 <https://github.com/rust-lang/rust/issues/87678>",
};
}

declare_lint! {
/// The `break_with_label_and_loop` lint detects labeled `break` expressions with
/// an unlabeled loop as their value expression.
Expand Down
11 changes: 5 additions & 6 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2663,10 +2663,9 @@ impl Target {
}
}

/// Returns a None if the UNSUPPORTED_CALLING_CONVENTIONS lint should be emitted
pub fn is_abi_supported(&self, abi: Abi) -> Option<bool> {
pub fn is_abi_supported(&self, abi: Abi) -> bool {
use Abi::*;
Some(match abi {
match abi {
Rust
| C { .. }
| System { .. }
Expand Down Expand Up @@ -2722,9 +2721,9 @@ impl Target {
// architectures for which these calling conventions are actually well defined.
Stdcall { .. } | Fastcall { .. } if self.arch == "x86" => true,
Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
// Return a `None` for other cases so that we know to emit a future compat lint.
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => return None,
})
// Reject these calling conventions everywhere else.
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => false,
}
}

/// Minimum integer size in bits that this target can perform atomic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(unsupported_calling_conventions)]
#![feature(abi_vectorcall)]
#![feature(const_extern_fn)]

extern "C-unwind" fn c_unwind() {}
Expand All @@ -8,7 +8,7 @@ extern "system" fn system() {}
//~^ ERROR: this could be a `const fn`
extern "system-unwind" fn system_unwind() {}
//~^ ERROR: this could be a `const fn`
pub extern "stdcall" fn std_call() {}
pub extern "vectorcall" fn vector_call() {}
//~^ ERROR: this could be a `const fn`
pub extern "stdcall-unwind" fn std_call_unwind() {}
pub extern "vectorcall-unwind" fn vector_call_unwind() {}
//~^ ERROR: this could be a `const fn`
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ LL | const extern "system-unwind" fn system_unwind() {}
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:11:1
|
LL | pub extern "stdcall" fn std_call() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | pub extern "vectorcall" fn vector_call() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `const`
|
LL | pub const extern "stdcall" fn std_call() {}
LL | pub const extern "vectorcall" fn vector_call() {}
| +++++

error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const_with_const_extern_fn.rs:13:1
|
LL | pub extern "stdcall-unwind" fn std_call_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | pub extern "vectorcall-unwind" fn vector_call_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `const`
|
LL | pub const extern "stdcall-unwind" fn std_call_unwind() {}
LL | pub const extern "vectorcall-unwind" fn vector_call_unwind() {}
| +++++

error: aborting due to 5 previous errors
Expand Down
8 changes: 2 additions & 6 deletions tests/ui/abi/unsupported.aarch64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,12 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

error: aborting due to 7 previous errors; 1 warning emitted
error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0570`.
8 changes: 2 additions & 6 deletions tests/ui/abi/unsupported.arm.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0570`.
8 changes: 2 additions & 6 deletions tests/ui/abi/unsupported.riscv32.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0570`.
8 changes: 2 additions & 6 deletions tests/ui/abi/unsupported.riscv64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0570`.
15 changes: 5 additions & 10 deletions tests/ui/abi/unsupported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,8 @@ extern "thiscall" fn thiscall() {}
//[riscv32]~^^^^ ERROR is not a supported ABI
//[riscv64]~^^^^^ ERROR is not a supported ABI
extern "stdcall" fn stdcall() {}
//[x64]~^ WARN use of calling convention not supported
//[x64]~^^ WARN this was previously accepted
//[arm]~^^^ WARN use of calling convention not supported
//[arm]~^^^^ WARN this was previously accepted
//[aarch64]~^^^^^ WARN use of calling convention not supported
//[aarch64]~^^^^^^ WARN this was previously accepted
//[riscv32]~^^^^^^^ WARN use of calling convention not supported
//[riscv32]~^^^^^^^^ WARN this was previously accepted
//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported
//[riscv64]~^^^^^^^^^^ WARN this was previously accepted
//[x64]~^ ERROR is not a supported ABI
//[arm]~^^ ERROR is not a supported ABI
//[aarch64]~^^^ ERROR is not a supported ABI
//[riscv32]~^^^^ ERROR is not a supported ABI
//[riscv64]~^^^^^ ERROR is not a supported ABI
8 changes: 2 additions & 6 deletions tests/ui/abi/unsupported.x64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,12 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
LL | extern "thiscall" fn thiscall() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 7 previous errors

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

0 comments on commit cee68d8

Please sign in to comment.