From: Pierre-Emmanuel Patry <[email protected]>
llvm_asm was never meant to be completely supported since it has been
replaced with the asm macro but we still need it to compile some parts
of libcore, previously the compiler was aborting when an unsupported
llvm_asm construct was found.
gcc/rust/ChangeLog:
* ast/rust-expr.h: Add const getters to llvm members.
* hir/rust-ast-lower-expr.cc (check_llvm_asm_support): Check llvm_asm
usage validity.
(ASTLoweringExpr::visit): Emit an error message instead of aborting.
Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
gcc/rust/ast/rust-expr.h | 7 ++++++
gcc/rust/hir/rust-ast-lower-expr.cc | 33 +++++++++++++++++++++++------
2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 8e5abe15219..ee3919a9a91 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -5687,6 +5687,10 @@ public:
}
std::vector<TupleTemplateStr> &get_templates () { return templates; }
+ const std::vector<TupleTemplateStr> &get_templates () const
+ {
+ return templates;
+ }
Expr::Kind get_expr_kind () const override
{
@@ -5705,9 +5709,12 @@ public:
void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; }
std::vector<LlvmOperand> &get_inputs () { return inputs; }
+ const std::vector<LlvmOperand> &get_inputs () const { return inputs; }
std::vector<LlvmOperand> &get_outputs () { return outputs; }
+ const std::vector<LlvmOperand> &get_outputs () const { return outputs; }
std::vector<TupleClobber> &get_clobbers () { return clobbers; }
+ const std::vector<TupleClobber> &get_clobbers () const { return clobbers; }
};
} // namespace AST
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 85171b0e886..a1e24eee745 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -994,6 +994,23 @@ ASTLoweringExpr::visit (AST::InlineAsm &expr)
expr.get_options (), mapping);
}
+namespace {
+// We're not really supporting llvm_asm, only the bare minimum for libcore's
+// blackbox
+// llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+bool
+check_llvm_asm_support (const std::vector<LlvmOperand> &inputs,
+ const std::vector<LlvmOperand> &outputs,
+ const AST::LlvmInlineAsm &expr)
+{
+ return outputs.size () == 0 && inputs.size () <= 1
+ && expr.get_clobbers ().size () <= 1
+ && expr.get_templates ().size () == 1
+ && expr.get_templates ()[0].symbol == "";
+}
+
+} // namespace
+
void
ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
{
@@ -1026,13 +1043,15 @@ ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
expr.is_stack_aligned (),
expr.get_dialect ()};
- // We're not really supporting llvm_asm, only the bare minimum
- // we're quite conservative here as the current code support more usecase.
- rust_assert (outputs.size () == 0);
- rust_assert (inputs.size () <= 1);
- rust_assert (expr.get_clobbers ().size () <= 1);
- rust_assert (expr.get_templates ().size () == 1);
- rust_assert (expr.get_templates ()[0].symbol == "");
+ if (!check_llvm_asm_support (inputs, outputs, expr))
+ {
+ rust_error_at (expr.get_locus (), "unsupported %qs construct",
+ "llvm_asm");
+ rust_inform (
+ expr.get_locus (),
+ "%<llvm_asm%> has been replaced with %<asm%>, gccrs only supports a "
+ "subset of %<llvm_asm%> to compile libcore");
+ }
translated
= new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
--
2.50.1