Skip to content

Commit

Permalink
Auto merge of #86231 - nagisa:nagisa/abi-allowlist, r=petrochenkov
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jul 6, 2021
2 parents d04ec47 + 8240e7a commit b09dad3
Show file tree
Hide file tree
Showing 101 changed files with 1,507 additions and 1,038 deletions.
47 changes: 47 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Expand Up @@ -2974,6 +2974,7 @@ declare_lint_pass! {
LARGE_ASSIGNMENTS,
FUTURE_PRELUDE_COLLISION,
RESERVED_PREFIX,
UNSUPPORTED_CALLING_CONVENTIONS,
]
}

Expand Down Expand Up @@ -3303,3 +3304,49 @@ declare_lint! {
};
crate_level_only
}

declare_lint! {
/// The `unsupported_calling_conventions` lint is output whenever there is an 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 {
reference: "issue #00000 <https://github.com/rust-lang/rust/issues/00000>",
};
}
4 changes: 1 addition & 3 deletions compiler/rustc_target/src/spec/aarch64_apple_ios.rs
Expand Up @@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
use crate::spec::{FramePointer, Target, TargetOptions};

pub fn target() -> Target {
let base = opts("ios", Arch::Arm64);
Target {
llvm_target: "arm64-apple-ios".to_string(),
pointer_width: 64,
Expand All @@ -11,7 +10,6 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,
frame_pointer: FramePointer::NonLeaf,
// Taken from a clang build on Xcode 11.4.1.
Expand All @@ -25,7 +23,7 @@ pub fn target() -> Target {
darwinpcs\0\
-Os\0"
.to_string(),
..base
..opts("ios", Arch::Arm64)
},
}
}
4 changes: 1 addition & 3 deletions compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
Expand Up @@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
use crate::spec::{FramePointer, Target, TargetOptions};

pub fn target() -> Target {
let base = opts("ios", Arch::Arm64_macabi);
Target {
llvm_target: "arm64-apple-ios14.0-macabi".to_string(),
pointer_width: 64,
Expand All @@ -11,7 +10,6 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a12".to_string(),
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,
frame_pointer: FramePointer::NonLeaf,
// Taken from a clang build on Xcode 11.4.1.
Expand All @@ -23,7 +21,7 @@ pub fn target() -> Target {
-disable-llvm-passes\0\
-Os\0"
.to_string(),
..base
..opts("ios", Arch::Arm64_macabi)
},
}
}
1 change: 0 additions & 1 deletion compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs
Expand Up @@ -19,7 +19,6 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,
frame_pointer: FramePointer::NonLeaf,
// Taken from a clang build on Xcode 11.4.1.
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
Expand Up @@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
use crate::spec::{FramePointer, Target, TargetOptions};

pub fn target() -> Target {
let base = opts("tvos", Arch::Arm64);
Target {
llvm_target: "arm64-apple-tvos".to_string(),
pointer_width: 64,
Expand All @@ -11,10 +10,9 @@ pub fn target() -> Target {
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".to_string(),
max_atomic_width: Some(128),
unsupported_abis: super::arm_base::unsupported_abis(),
forces_embed_bitcode: true,
frame_pointer: FramePointer::NonLeaf,
..base
..opts("tvos", Arch::Arm64)
},
}
}
Expand Up @@ -2,19 +2,16 @@ use crate::abi::Endian;
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(128);

Target {
llvm_target: "aarch64_be-unknown-linux-gnu".to_string(),
pointer_width: 64,
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
unsupported_abis: super::arm_base::unsupported_abis(),
max_atomic_width: Some(128),
mcount: "\u{1}_mcount".to_string(),
endian: Endian::Big,
..base
..super::linux_gnu_base::opts()
},
}
}
Expand Up @@ -10,11 +10,6 @@ pub fn target() -> Target {
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
unsupported_abis: super::arm_base::unsupported_abis(),
mcount: "\u{1}_mcount".to_string(),
endian: Endian::Big,
..base
},
options: TargetOptions { mcount: "\u{1}_mcount".to_string(), endian: Endian::Big, ..base },
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/aarch64_fuchsia.rs
@@ -1,15 +1,15 @@
use crate::spec::{SanitizerSet, Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::fuchsia_base::opts();
base.max_atomic_width = Some(128);
base.supported_sanitizers = SanitizerSet::ADDRESS;

Target {
llvm_target: "aarch64-fuchsia".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
options: TargetOptions {
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::ADDRESS,
..super::fuchsia_base::opts()
},
}
}
15 changes: 8 additions & 7 deletions compiler/rustc_target/src/spec/aarch64_linux_android.rs
Expand Up @@ -4,17 +4,18 @@ use crate::spec::{SanitizerSet, Target, TargetOptions};
// for target ABI requirements.

pub fn target() -> Target {
let mut base = super::android_base::opts();
base.max_atomic_width = Some(128);
// As documented in https://developer.android.com/ndk/guides/cpu-features.html
// the neon (ASIMD) and FP must exist on all android aarch64 targets.
base.features = "+neon,+fp-armv8".to_string();
base.supported_sanitizers = SanitizerSet::HWADDRESS;
Target {
llvm_target: "aarch64-linux-android".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
options: TargetOptions {
max_atomic_width: Some(128),
// As documented in https://developer.android.com/ndk/guides/cpu-features.html
// the neon (ASIMD) and FP must exist on all android aarch64 targets.
features: "+neon,+fp-armv8".to_string(),
supported_sanitizers: SanitizerSet::HWADDRESS,
..super::android_base::opts()
},
}
}
5 changes: 1 addition & 4 deletions compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
@@ -1,14 +1,11 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.max_atomic_width = Some(128);

Target {
llvm_target: "aarch64-unknown-freebsd".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
options: TargetOptions { max_atomic_width: Some(128), ..super::freebsd_base::opts() },
}
}
17 changes: 7 additions & 10 deletions compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
@@ -1,23 +1,20 @@
use crate::spec::{SanitizerSet, Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(128);
base.supported_sanitizers = SanitizerSet::ADDRESS
| SanitizerSet::LEAK
| SanitizerSet::MEMORY
| SanitizerSet::THREAD
| SanitizerSet::HWADDRESS;

Target {
llvm_target: "aarch64-unknown-linux-gnu".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
unsupported_abis: super::arm_base::unsupported_abis(),
mcount: "\u{1}_mcount".to_string(),
..base
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::ADDRESS
| SanitizerSet::LEAK
| SanitizerSet::MEMORY
| SanitizerSet::THREAD
| SanitizerSet::HWADDRESS,
..super::linux_gnu_base::opts()
},
}
}
@@ -1,18 +1,15 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(128);

Target {
llvm_target: "aarch64-unknown-linux-gnu_ilp32".to_string(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
unsupported_abis: super::arm_base::unsupported_abis(),
max_atomic_width: Some(128),
mcount: "\u{1}_mcount".to_string(),
..base
..super::linux_gnu_base::opts()
},
}
}
6 changes: 1 addition & 5 deletions compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
Expand Up @@ -9,10 +9,6 @@ pub fn target() -> Target {
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
unsupported_abis: super::arm_base::unsupported_abis(),
mcount: "\u{1}_mcount".to_string(),
..base
},
options: TargetOptions { mcount: "\u{1}_mcount".to_string(), ..base },
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
@@ -1,15 +1,15 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
base.max_atomic_width = Some(128);
base.unsupported_abis = super::arm_base::unsupported_abis();

Target {
llvm_target: "aarch64-unknown-netbsd".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions { mcount: "__mcount".to_string(), ..base },
options: TargetOptions {
mcount: "__mcount".to_string(),
max_atomic_width: Some(128),
..super::netbsd_base::opts()
},
}
}
1 change: 0 additions & 1 deletion compiler/rustc_target/src/spec/aarch64_unknown_none.rs
Expand Up @@ -18,7 +18,6 @@ pub fn target() -> Target {
disable_redzone: true,
max_atomic_width: Some(128),
panic_strategy: PanicStrategy::Abort,
unsupported_abis: super::arm_base::unsupported_abis(),
..Default::default()
};
Target {
Expand Down
Expand Up @@ -18,7 +18,6 @@ pub fn target() -> Target {
disable_redzone: true,
max_atomic_width: Some(128),
panic_strategy: PanicStrategy::Abort,
unsupported_abis: super::arm_base::unsupported_abis(),
..Default::default()
};
Target {
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
@@ -1,15 +1,11 @@
use crate::spec::Target;
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::openbsd_base::opts();
base.max_atomic_width = Some(128);
base.unsupported_abis = super::arm_base::unsupported_abis();

Target {
llvm_target: "aarch64-unknown-openbsd".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: base,
options: TargetOptions { max_atomic_width: Some(128), ..super::openbsd_base::opts() },
}
}
5 changes: 1 addition & 4 deletions compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
@@ -1,14 +1,11 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
base.max_atomic_width = Some(128);

Target {
llvm_target: "aarch64-unknown-linux-gnu".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
options: TargetOptions { max_atomic_width: Some(128), ..super::vxworks_base::opts() },
}
}

0 comments on commit b09dad3

Please sign in to comment.