about summary refs log tree commit diff
path: root/compiler/rustc_lint_defs/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-10-12 23:00:55 +0200
committerGitHub <noreply@github.com>2024-10-12 23:00:55 +0200
commit57be141f8a03edd6236dc00a3772fc27673a64c3 (patch)
tree9db209e80f16798851f9e7ac7e8149573f32a7ac /compiler/rustc_lint_defs/src
parent6b9676b45431a1e531b9c5f7bd289fc36a312749 (diff)
parent867e776fa6220b17963c34b572fb3c8aa0ace2a3 (diff)
Rollup merge of #128784 - tdittr:check-abi-on-fn-ptr, r=compiler-errors
Check ABI target compatibility for function pointers

Tracking issue: https://github.com/rust-lang/rust/issues/130260
Related tracking issue: #87678

Compatibility of an ABI for a target was previously only performed on function definitions and `extern` blocks. This PR adds it also to function pointers to be consistent.

This might have broken some of the `tests/ui/` depending on the platform, so a try run seems like a good idea.

Also this might break existing code, because we now emit extra errors. Does this require a crater run?

# Example
```rust
// build with: --target=x86_64-unknown-linux-gnu

// These raise E0570
extern "thiscall" fn foo() {}
extern "thiscall" { fn bar() }

// This did not raise any error
fn baz(f: extern "thiscall" fn()) { f() }
```

# Open Questions
* [x] Should this report a future incompatibility warning like #87678 ?
* [ ] Is this the best place to perform the check?
Diffstat (limited to 'compiler/rustc_lint_defs/src')
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 827791c54be..23dc5214fe2 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -124,6 +124,7 @@ declare_lint_pass! {
         UNSTABLE_NAME_COLLISIONS,
         UNSTABLE_SYNTAX_PRE_EXPANSION,
         UNSUPPORTED_CALLING_CONVENTIONS,
+        UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
         UNUSED_ASSIGNMENTS,
         UNUSED_ASSOCIATED_TYPE_BOUNDS,
         UNUSED_ATTRIBUTES,
@@ -3840,6 +3841,50 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
+    /// a target dependent calling convention on a target that does not support this calling
+    /// convention on a function pointer.
+    ///
+    /// 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.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (needs specific targets)
+    /// fn stdcall_ptr(f: extern "stdcall" fn ()) {
+    ///     f()
+    /// }
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: use of calling convention not supported on this target on function pointer
+    ///   --> $DIR/unsupported.rs:34:15
+    ///    |
+    /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
+    ///    |               ^^^^^^^^^^^^^^^^^^^^^^^^
+    ///    |
+    ///    = 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
+    ///    = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+    /// ```
+    ///
+    /// ### 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_FN_PTR_CALLING_CONVENTIONS,
+    Warn,
+    "use of unsupported calling convention for function pointer",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
+    };
+}
+
+declare_lint! {
     /// The `break_with_label_and_loop` lint detects labeled `break` expressions with
     /// an unlabeled loop as their value expression.
     ///