about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-25 15:17:47 +0000
committerbors <bors@rust-lang.org>2024-10-25 15:17:47 +0000
commit6faf0bd3e561f1a0c81f3eafe0ce0e688385d70e (patch)
tree54fce6cbbbdf6ce5b564da5d87ae4c078fc97c32 /compiler/rustc_target/src
parent45089ec19ebebec88bace6ec237244ff0eaa7ad3 (diff)
parent5af56cac38fa48e4228e5e123d060e85eb1acbf7 (diff)
Auto merge of #127731 - veluca93:abi_checks, r=RalfJung
Emit future-incompatibility lint when calling/declaring functions with vectors that require missing target feature

On some architectures, vector types may have a different ABI depending on whether the relevant target features are enabled. (The ABI when the feature is disabled is often not specified, but LLVM implements some de-facto ABI.)

As discussed in https://github.com/rust-lang/lang-team/issues/235, this turns out to very easily lead to unsound code.

This commit makes it a post-monomorphization error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. This ensures that these functions are always called with a consistent ABI.

See the [nomination comment](https://github.com/rust-lang/rust/pull/127731#issuecomment-2288558187) for more discussion.

r? RalfJung

Part of https://github.com/rust-lang/rust/issues/116558
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/target_features.rs17
1 files changed, 17 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index e92366d5c5c..0d16c9a96aa 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -522,6 +522,13 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Stability)> {
         .map(|(f, s, _)| (f, s))
 }
 
+// These arrays represent the least-constraining feature that is required for vector types up to a
+// certain size to have their "proper" ABI on each architecture.
+// Note that they must be kept sorted by vector size.
+const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
+    &[(128, "sse"), (256, "avx"), (512, "avx512f")];
+const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
+
 impl super::spec::Target {
     pub fn supported_target_features(
         &self,
@@ -543,6 +550,16 @@ impl super::spec::Target {
         }
     }
 
+    // Returns None if we do not support ABI checks on the given target yet.
+    pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
+        match &*self.arch {
+            "x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            // FIXME: add support for non-tier1 architectures
+            _ => None,
+        }
+    }
+
     pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
         match &*self.arch {
             "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,