about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/messages.ftl5
-rw-r--r--compiler/rustc_lint/src/builtin.rs57
-rw-r--r--compiler/rustc_lint/src/lints.rs4
-rw-r--r--tests/ui/asm/binary_asm_labels.stderr20
-rw-r--r--tests/ui/asm/binary_asm_labels_allowed.rs17
5 files changed, 77 insertions, 26 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 79d52914381..7d7b97e2eb1 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -403,8 +403,9 @@ lint_inner_macro_attribute_unstable = inner macro attributes are unstable
 
 lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly
     .label = use a different label that doesn't start with `0` or `1`
-    .note = an LLVM bug makes these labels ambiguous with a binary literal number
-    .note = see <https://bugs.llvm.org/show_bug.cgi?id=36144> for more information
+    .help = start numbering with `2` instead
+    .note1 = an LLVM bug makes these labels ambiguous with a binary literal number on x86
+    .note2 = see <https://github.com/llvm/llvm-project/issues/99547> for more information
 
 lint_invalid_asm_label_format_arg = avoid using named labels in inline assembly
     .help = only local labels of the form `<number>:` should be used in inline asm
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 485c214ac9d..9ebada0fff3 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -66,6 +66,7 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, InnerSpan, Span};
 use rustc_target::abi::Abi;
+use rustc_target::asm::InlineAsmArch;
 use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
@@ -2739,8 +2740,9 @@ declare_lint! {
     ///
     /// ### Example
     ///
-    /// ```rust,compile_fail
-    /// # #![feature(asm_experimental_arch)]
+    /// ```rust,ignore (fails on non-x86_64)
+    /// #![cfg(target_arch = "x86_64")]
+    ///
     /// use std::arch::asm;
     ///
     /// fn main() {
@@ -2750,19 +2752,32 @@ declare_lint! {
     /// }
     /// ```
     ///
-    /// {{produces}}
+    /// This will produce:
+    ///
+    /// ```text
+    /// error: avoid using labels containing only the digits `0` and `1` in inline assembly
+    ///  --> <source>:7:15
+    ///   |
+    /// 7 |         asm!("0: jmp 0b");
+    ///   |               ^ use a different label that doesn't start with `0` or `1`
+    ///   |
+    ///   = help: start numbering with `2` instead
+    ///   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+    ///   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
+    ///   = note: `#[deny(binary_asm_labels)]` on by default
+    /// ```
     ///
     /// ### Explanation
     ///
-    /// A [LLVM bug] causes this code to fail to compile because it interprets the `0b` as a binary
-    /// literal instead of a reference to the previous local label `0`. Note that even though the
-    /// bug is marked as fixed, it only fixes a specific usage of intel syntax within standalone
-    /// files, not inline assembly. To work around this bug, don't use labels that could be
-    /// confused with a binary literal.
+    /// An [LLVM bug] causes this code to fail to compile because it interprets the `0b` as a binary
+    /// literal instead of a reference to the previous local label `0`. To work around this bug,
+    /// don't use labels that could be confused with a binary literal.
+    ///
+    /// This behavior is platform-specific to x86 and x86-64.
     ///
     /// See the explanation in [Rust By Example] for more details.
     ///
-    /// [LLVM bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
+    /// [LLVM bug]: https://github.com/llvm/llvm-project/issues/99547
     /// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels
     pub BINARY_ASM_LABELS,
     Deny,
@@ -2908,16 +2923,22 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
                                 InvalidAsmLabel::FormatArg { missing_precise_span },
                             );
                         }
-                        AsmLabelKind::Binary => {
-                            // the binary asm issue only occurs when using intel syntax
-                            if !options.contains(InlineAsmOptions::ATT_SYNTAX) {
-                                cx.emit_span_lint(
-                                    BINARY_ASM_LABELS,
-                                    span,
-                                    InvalidAsmLabel::Binary { missing_precise_span, span },
-                                )
-                            }
+                        // the binary asm issue only occurs when using intel syntax on x86 targets
+                        AsmLabelKind::Binary
+                            if !options.contains(InlineAsmOptions::ATT_SYNTAX)
+                                && matches!(
+                                    cx.tcx.sess.asm_arch,
+                                    Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) | None
+                                ) =>
+                        {
+                            cx.emit_span_lint(
+                                BINARY_ASM_LABELS,
+                                span,
+                                InvalidAsmLabel::Binary { missing_precise_span, span },
+                            )
                         }
+                        // No lint on anything other than x86
+                        AsmLabelKind::Binary => (),
                     };
                 }
             }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ac5511faf19..6c5f366727f 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2074,7 +2074,9 @@ pub enum InvalidAsmLabel {
         missing_precise_span: bool,
     },
     #[diag(lint_invalid_asm_label_binary)]
-    #[note]
+    #[help]
+    #[note(lint_note1)]
+    #[note(lint_note2)]
     Binary {
         #[note(lint_invalid_asm_label_no_span)]
         missing_precise_span: bool,
diff --git a/tests/ui/asm/binary_asm_labels.stderr b/tests/ui/asm/binary_asm_labels.stderr
index 1f2943084f1..206d2da1779 100644
--- a/tests/ui/asm/binary_asm_labels.stderr
+++ b/tests/ui/asm/binary_asm_labels.stderr
@@ -4,7 +4,9 @@ error: avoid using labels containing only the digits `0` and `1` in inline assem
 LL |         asm!("0: jmp 0b");
    |               ^ use a different label that doesn't start with `0` or `1`
    |
-   = note: an LLVM bug makes these labels ambiguous with a binary literal number
+   = help: start numbering with `2` instead
+   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
    = note: `#[deny(binary_asm_labels)]` on by default
 
 error: avoid using labels containing only the digits `0` and `1` in inline assembly
@@ -13,7 +15,9 @@ error: avoid using labels containing only the digits `0` and `1` in inline assem
 LL |         asm!("1: jmp 1b");
    |               ^ use a different label that doesn't start with `0` or `1`
    |
-   = note: an LLVM bug makes these labels ambiguous with a binary literal number
+   = help: start numbering with `2` instead
+   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
 
 error: avoid using labels containing only the digits `0` and `1` in inline assembly
   --> $DIR/binary_asm_labels.rs:13:15
@@ -21,7 +25,9 @@ error: avoid using labels containing only the digits `0` and `1` in inline assem
 LL |         asm!("10: jmp 10b");
    |               ^^ use a different label that doesn't start with `0` or `1`
    |
-   = note: an LLVM bug makes these labels ambiguous with a binary literal number
+   = help: start numbering with `2` instead
+   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
 
 error: avoid using labels containing only the digits `0` and `1` in inline assembly
   --> $DIR/binary_asm_labels.rs:14:15
@@ -29,7 +35,9 @@ error: avoid using labels containing only the digits `0` and `1` in inline assem
 LL |         asm!("01: jmp 01b");
    |               ^^ use a different label that doesn't start with `0` or `1`
    |
-   = note: an LLVM bug makes these labels ambiguous with a binary literal number
+   = help: start numbering with `2` instead
+   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
 
 error: avoid using labels containing only the digits `0` and `1` in inline assembly
   --> $DIR/binary_asm_labels.rs:15:15
@@ -37,7 +45,9 @@ error: avoid using labels containing only the digits `0` and `1` in inline assem
 LL |         asm!("1001101: jmp 1001101b");
    |               ^^^^^^^ use a different label that doesn't start with `0` or `1`
    |
-   = note: an LLVM bug makes these labels ambiguous with a binary literal number
+   = help: start numbering with `2` instead
+   = note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
+   = note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/asm/binary_asm_labels_allowed.rs b/tests/ui/asm/binary_asm_labels_allowed.rs
new file mode 100644
index 00000000000..a21ab8d70f5
--- /dev/null
+++ b/tests/ui/asm/binary_asm_labels_allowed.rs
@@ -0,0 +1,17 @@
+//@ build-pass
+//@ only-aarch64
+
+// The `binary_asm_labels` lint should only be raised on `x86`. Make sure it
+// doesn't get raised on other platforms.
+
+use std::arch::asm;
+
+fn main() {
+    unsafe {
+        asm!("0: bl 0b");
+        asm!("1: bl 1b");
+        asm!("10: bl 10b");
+        asm!("01: bl 01b");
+        asm!("1001101: bl 1001101b");
+    }
+}