about summary refs log tree commit diff
path: root/compiler/rustc_lint_defs/src/builtin.rs
diff options
context:
space:
mode:
authorLuca Versari <veluca93@gmail.com>2024-07-13 19:35:05 +0200
committerLuca Versari <veluca93@gmail.com>2024-11-01 22:24:35 +0100
commitc8b76bcf58298cced4ef3ca9dd823eb318fc11f5 (patch)
tree3418691183ea0ba07f66ad7a2aba5ce557105dff /compiler/rustc_lint_defs/src/builtin.rs
parent4d296eabe4c5cfbce9bb68e6221bca2165aae97b (diff)
downloadrust-c8b76bcf58298cced4ef3ca9dd823eb318fc11f5.tar.gz
rust-c8b76bcf58298cced4ef3ca9dd823eb318fc11f5.zip
Emit warning when calling/declaring functions with unavailable vectors.
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 rust-lang/lang-team#235, this turns out to very easily
lead to unsound code.

This commit makes it a post-monomorphization future-incompat warning 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.

Part of #116558
Diffstat (limited to 'compiler/rustc_lint_defs/src/builtin.rs')
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 06a3e4a6743..51146cfd2e9 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -16,6 +16,7 @@ declare_lint_pass! {
     /// that are used by other parts of the compiler.
     HardwiredLints => [
         // tidy-alphabetical-start
+        ABI_UNSUPPORTED_VECTOR_TYPES,
         ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
         AMBIGUOUS_ASSOCIATED_ITEMS,
         AMBIGUOUS_GLOB_IMPORTS,
@@ -5031,3 +5032,69 @@ declare_lint! {
     };
     crate_level_only
 }
+
+declare_lint! {
+    /// The `abi_unsupported_vector_types` lint detects function definitions and calls
+    /// whose ABI depends on enabling certain target features, but those features are not enabled.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (fails on non-x86_64)
+    /// extern "C" fn missing_target_feature(_: std::arch::x86_64::__m256) {
+    ///   todo!()
+    /// }
+    ///
+    /// #[target_feature(enable = "avx")]
+    /// unsafe extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
+    ///   todo!()
+    /// }
+    ///
+    /// fn main() {
+    ///   let v = unsafe { std::mem::zeroed() };
+    ///   unsafe { with_target_feature(v); }
+    /// }
+    /// ```
+    ///
+    /// ```text
+    /// warning: ABI error: this function call uses a avx vector type, which is not enabled in the caller
+    ///  --> lint_example.rs:18:12
+    ///   |
+    ///   |   unsafe { with_target_feature(v); }
+    ///   |            ^^^^^^^^^^^^^^^^^^^^^^ function called here
+    ///   |
+    ///   = 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 #116558 <https://github.com/rust-lang/rust/issues/116558>
+    ///   = help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
+    ///   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+    ///
+    ///
+    /// warning: ABI error: this function definition uses a avx vector type, which is not enabled
+    ///  --> lint_example.rs:3:1
+    ///   |
+    ///   | pub extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
+    ///   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+    ///   |
+    ///   = 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 #116558 <https://github.com/rust-lang/rust/issues/116558>
+    ///   = help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
+    /// ```
+    ///
+    ///
+    ///
+    /// ### Explanation
+    ///
+    /// The C ABI for `__m256` requires the value to be passed in an AVX register,
+    /// which is only possible when the `avx` target feature is enabled.
+    /// Therefore, `missing_target_feature` cannot be compiled without that target feature.
+    /// A similar (but complementary) message is triggered when `with_target_feature` is called
+    /// by a function that does not enable the `avx` target feature.
+    ///
+    /// Note that this lint is very similar to the `-Wpsabi` warning in `gcc`/`clang`.
+    pub ABI_UNSUPPORTED_VECTOR_TYPES,
+    Warn,
+    "this function call or definition uses a vector type which is not enabled",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reference: "issue #116558 <https://github.com/rust-lang/rust/issues/116558>",
+    };
+}