Skip to content

Commit b09dad3

Browse files
committedJul 6, 2021
Auto merge of #86231 - nagisa:nagisa/abi-allowlist, r=petrochenkov
Replace per-target ABI denylist with an allowlist It makes very little sense to maintain denylists of ABIs when, as far as non-generic ABIs are concerned, targets usually only support a small subset of the available ABIs. This has historically been a cause of bugs such as us allowing use of the platform-specific ABIs on x86 targets – these in turn would cause LLVM errors or assertions to fire. In this PR we got rid of the per-target ABI denylists, and instead compute which ABIs are supported with a simple match based on, mostly, the `Target::arch` field. Among other things, this makes it impossible to forget to consider this problem (in either direction) and forces one to consider what the ABI support looks like when adding an ABI (rarely) rather than target (often), which should hopefully also reduce the cognitive load on both contributors as well as reviewers. Fixes #57182 Sponsored by: standard.ai --- ## Summary for teams One significant user-facing change after this PR is that there's now a future compat warning when building… * `stdcall`, `fastcall`, `thiscall` using code with targets other than 32-bit x86 (i386...i686) or *-windows-*; * `vectorcall` using code when building for targets other than x86 (either 32 or 64 bit) or *-windows-*. Previously these ABIs have been accepted much more broadly, even for architectures and targets where this made no sense (e.g. on wasm32) and would fall back to the C ABI. In practice this doesn't seem to be used too widely and the [breakages in crater](#86231 (comment)) that we see are mostly about Windows-specific code that was missing relevant `cfg`s and just happened to successfully `check` on Linux for one reason or another. The intention is that this warning becomes a hard error after some time.
·
1.90.01.55.0
2 parents d04ec47 + 8240e7a commit b09dad3

File tree

101 files changed

+1507
-1038
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1507
-1038
lines changed
 

‎compiler/rustc_lint_defs/src/builtin.rs‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,6 +2974,7 @@ declare_lint_pass! {
29742974
LARGE_ASSIGNMENTS,
29752975
FUTURE_PRELUDE_COLLISION,
29762976
RESERVED_PREFIX,
2977+
UNSUPPORTED_CALLING_CONVENTIONS,
29772978
]
29782979
}
29792980

@@ -3303,3 +3304,49 @@ declare_lint! {
33033304
};
33043305
crate_level_only
33053306
}
3307+
3308+
declare_lint! {
3309+
/// The `unsupported_calling_conventions` lint is output whenever there is an use of the
3310+
/// `stdcall`, `fastcall`, `thiscall`, `vectorcall` calling conventions (or their unwind
3311+
/// variants) on targets that cannot meaningfully be supported for the requested target.
3312+
///
3313+
/// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3314+
/// code, because this calling convention was never specified for those targets.
3315+
///
3316+
/// Historically MSVC toolchains have fallen back to the regular C calling convention for
3317+
/// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
3318+
/// hack across many more targets.
3319+
///
3320+
/// ### Example
3321+
///
3322+
/// ```rust,ignore (needs specific targets)
3323+
/// extern "stdcall" fn stdcall() {}
3324+
/// ```
3325+
///
3326+
/// This will produce:
3327+
///
3328+
/// ```text
3329+
/// warning: use of calling convention not supported on this target
3330+
/// --> $DIR/unsupported.rs:39:1
3331+
/// |
3332+
/// LL | extern "stdcall" fn stdcall() {}
3333+
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3334+
/// |
3335+
/// = note: `#[warn(unsupported_calling_conventions)]` on by default
3336+
/// = warning: this was previously accepted by the compiler but is being phased out;
3337+
/// it will become a hard error in a future release!
3338+
/// = note: for more information, see issue ...
3339+
/// ```
3340+
///
3341+
/// ### Explanation
3342+
///
3343+
/// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3344+
/// defined at all, but was previously accepted due to a bug in the implementation of the
3345+
/// compiler.
3346+
pub UNSUPPORTED_CALLING_CONVENTIONS,
3347+
Warn,
3348+
"use of unsupported calling convention",
3349+
@future_incompatible = FutureIncompatibleInfo {
3350+
reference: "issue #00000 <https://github.com/rust-lang/rust/issues/00000>",
3351+
};
3352+
}

‎compiler/rustc_target/src/spec/aarch64_apple_ios.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{FramePointer, Target, TargetOptions};
33

44
pub fn target() -> Target {
5-
let base = opts("ios", Arch::Arm64);
65
Target {
76
llvm_target: "arm64-apple-ios".to_string(),
87
pointer_width: 64,
@@ -11,7 +10,6 @@ pub fn target() -> Target {
1110
options: TargetOptions {
1211
features: "+neon,+fp-armv8,+apple-a7".to_string(),
1312
max_atomic_width: Some(128),
14-
unsupported_abis: super::arm_base::unsupported_abis(),
1513
forces_embed_bitcode: true,
1614
frame_pointer: FramePointer::NonLeaf,
1715
// Taken from a clang build on Xcode 11.4.1.
@@ -25,7 +23,7 @@ pub fn target() -> Target {
2523
darwinpcs\0\
2624
-Os\0"
2725
.to_string(),
28-
..base
26+
..opts("ios", Arch::Arm64)
2927
},
3028
}
3129
}

0 commit comments

Comments
 (0)
Please sign in to comment.