about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2024-10-11 00:27:16 +0100
committerGary Guo <gary@garyguo.net>2024-11-24 15:24:01 +0000
commit0178ba2c2547c3677b5624d684a392dccae12abc (patch)
tree580e52e487056b7c3e9393906bb4f74e52940b2a
parent73f8309300bce03e62c8a49e8a06b884175b5f88 (diff)
downloadrust-0178ba2c2547c3677b5624d684a392dccae12abc.tar.gz
rust-0178ba2c2547c3677b5624d684a392dccae12abc.zip
Make asm_goto_with_outputs a separate feature gate
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl2
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs44
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/codegen/asm/goto.rs2
-rw-r--r--tests/ui/asm/x86_64/goto.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr13
8 files changed, 68 insertions, 11 deletions
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index f704320c71d..93e1e25384e 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -181,6 +181,8 @@ ast_lowering_underscore_expr_lhs_assign =
     .label = `_` not allowed here
 
 ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
+ast_lowering_unstable_inline_assembly_label_operand_with_outputs =
+    using both label and output operands for inline assembly is unstable
 ast_lowering_unstable_inline_assembly_label_operands =
     label operands for inline assembly are unstable
 ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 215e6d84d0f..520274278a1 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -239,15 +239,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         }
                     }
                     InlineAsmOperand::Label { block } => {
-                        if !self.tcx.features().asm_goto() {
-                            feature_err(
-                                sess,
-                                sym::asm_goto,
-                                *op_sp,
-                                fluent::ast_lowering_unstable_inline_assembly_label_operands,
-                            )
-                            .emit();
-                        }
                         hir::InlineAsmOperand::Label { block: self.lower_block(block, false) }
                     }
                 };
@@ -466,6 +457,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
+        // Feature gate checking for asm goto.
+        if let Some((_, op_sp)) =
+            operands.iter().find(|(op, _)| matches!(op, hir::InlineAsmOperand::Label { .. }))
+        {
+            if !self.tcx.features().asm_goto() {
+                feature_err(
+                    sess,
+                    sym::asm_goto,
+                    *op_sp,
+                    fluent::ast_lowering_unstable_inline_assembly_label_operands,
+                )
+                .emit();
+            }
+
+            // In addition, check if an output operand is used.
+            // This is gated behind an additional feature.
+            let output_operand_used = operands.iter().any(|(op, _)| {
+                matches!(
+                    op,
+                    hir::InlineAsmOperand::Out { expr: Some(_), .. }
+                        | hir::InlineAsmOperand::InOut { .. }
+                        | hir::InlineAsmOperand::SplitInOut { out_expr: Some(_), .. }
+                )
+            });
+            if output_operand_used && !self.tcx.features().asm_goto_with_outputs() {
+                feature_err(
+                    sess,
+                    sym::asm_goto_with_outputs,
+                    *op_sp,
+                    fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs,
+                )
+                .emit();
+            }
+        }
+
         let operands = self.arena.alloc_from_iter(operands);
         let template = self.arena.alloc_from_iter(asm.template.iter().cloned());
         let template_strs = self.arena.alloc_from_iter(
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index cf0f2a7e48c..6a231397615 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -378,6 +378,8 @@ declare_features! (
     (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
     /// Allows using `label` operands in inline assembly.
     (unstable, asm_goto, "1.78.0", Some(119364)),
+    /// Allows using `label` operands in inline assembly together with output operands.
+    (unstable, asm_goto_with_outputs, "CURRENT_RUSTC_VERSION", Some(119364)),
     /// Allows the `may_unwind` option in inline assembly.
     (unstable, asm_unwind, "1.58.0", Some(93334)),
     /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 3d0ec2afa2b..0e4d937d6fd 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -417,6 +417,7 @@ symbols! {
         asm_const,
         asm_experimental_arch,
         asm_goto,
+        asm_goto_with_outputs,
         asm_sym,
         asm_unwind,
         assert,
diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs
index 3193d3aa145..c40a43fbe1b 100644
--- a/tests/codegen/asm/goto.rs
+++ b/tests/codegen/asm/goto.rs
@@ -2,7 +2,7 @@
 //@ only-x86_64
 
 #![crate_type = "rlib"]
-#![feature(asm_goto)]
+#![feature(asm_goto, asm_goto_with_outputs)]
 
 use std::arch::asm;
 
diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs
index d23018a05f5..50e7441509a 100644
--- a/tests/ui/asm/x86_64/goto.rs
+++ b/tests/ui/asm/x86_64/goto.rs
@@ -3,7 +3,7 @@
 //@ needs-asm-support
 
 #![deny(unreachable_code)]
-#![feature(asm_goto)]
+#![feature(asm_goto, asm_goto_with_outputs)]
 
 use std::arch::asm;
 
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs
new file mode 100644
index 00000000000..294827f78d2
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs
@@ -0,0 +1,13 @@
+//@ only-x86_64
+
+#![feature(asm_goto)]
+
+use std::arch::asm;
+
+fn main() {
+    let mut _out: u64;
+    unsafe {
+        asm!("mov {}, 1", "jmp {}", out(reg) _out, label {});
+        //~^ ERROR using both label and output operands for inline assembly is unstable
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr
new file mode 100644
index 00000000000..ff7a7d5760a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr
@@ -0,0 +1,13 @@
+error[E0658]: using both label and output operands for inline assembly is unstable
+  --> $DIR/feature-gate-asm_goto_with_outputs.rs:10:52
+   |
+LL |         asm!("mov {}, 1", "jmp {}", out(reg) _out, label {});
+   |                                                    ^^^^^^^^
+   |
+   = note: see issue #119364 <https://github.com/rust-lang/rust/issues/119364> for more information
+   = help: add `#![feature(asm_goto_with_outputs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.