about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs46
-rw-r--r--tests/ui/asm/fail-const-eval-issue-121099.rs11
-rw-r--r--tests/ui/asm/fail-const-eval-issue-121099.stderr15
3 files changed, 55 insertions, 17 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 7b7cdae0ed6..df564f705bc 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -2,6 +2,7 @@ use crate::base;
 use crate::common;
 use crate::traits::*;
 use rustc_hir as hir;
+use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::mir::mono::{Linkage, Visibility};
 use rustc_middle::ty;
@@ -40,23 +41,34 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                         .iter()
                         .map(|(op, op_sp)| match *op {
                             hir::InlineAsmOperand::Const { ref anon_const } => {
-                                let const_value = cx
-                                    .tcx()
-                                    .const_eval_poly(anon_const.def_id.to_def_id())
-                                    .unwrap_or_else(|_| {
-                                        span_bug!(*op_sp, "asm const cannot be resolved")
-                                    });
-                                let ty = cx
-                                    .tcx()
-                                    .typeck_body(anon_const.body)
-                                    .node_type(anon_const.hir_id);
-                                let string = common::asm_const_to_str(
-                                    cx.tcx(),
-                                    *op_sp,
-                                    const_value,
-                                    cx.layout_of(ty),
-                                );
-                                GlobalAsmOperandRef::Const { string }
+                                match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
+                                    Ok(const_value) => {
+                                        let ty = cx
+                                            .tcx()
+                                            .typeck_body(anon_const.body)
+                                            .node_type(anon_const.hir_id);
+                                        let string = common::asm_const_to_str(
+                                            cx.tcx(),
+                                            *op_sp,
+                                            const_value,
+                                            cx.layout_of(ty),
+                                        );
+                                        GlobalAsmOperandRef::Const { string }
+                                    }
+                                    Err(ErrorHandled::Reported { .. }) => {
+                                        // An error has already been reported and
+                                        // compilation is guaranteed to fail if execution
+                                        // hits this path. So an empty string instead of
+                                        // a stringified constant value will suffice.
+                                        GlobalAsmOperandRef::Const { string: String::new() }
+                                    }
+                                    Err(ErrorHandled::TooGeneric(_)) => {
+                                        span_bug!(
+                                            *op_sp,
+                                            "asm const cannot be resolved; too generic"
+                                        )
+                                    }
+                                }
                             }
                             hir::InlineAsmOperand::SymFn { ref anon_const } => {
                                 let ty = cx
diff --git a/tests/ui/asm/fail-const-eval-issue-121099.rs b/tests/ui/asm/fail-const-eval-issue-121099.rs
new file mode 100644
index 00000000000..bed6fc9b39f
--- /dev/null
+++ b/tests/ui/asm/fail-const-eval-issue-121099.rs
@@ -0,0 +1,11 @@
+//@ build-fail
+//@ needs-asm-support
+#![feature(asm_const)]
+
+use std::arch::global_asm;
+
+fn main() {}
+
+global_asm!("/* {} */", const 1 << 500); //~ ERROR evaluation of constant value failed [E0080]
+
+global_asm!("/* {} */", const 1 / 0); //~ ERROR evaluation of constant value failed [E0080]
diff --git a/tests/ui/asm/fail-const-eval-issue-121099.stderr b/tests/ui/asm/fail-const-eval-issue-121099.stderr
new file mode 100644
index 00000000000..51d283218d2
--- /dev/null
+++ b/tests/ui/asm/fail-const-eval-issue-121099.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/fail-const-eval-issue-121099.rs:9:31
+   |
+LL | global_asm!("/* {} */", const 1 << 500);
+   |                               ^^^^^^^^ attempt to shift left by `500_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/fail-const-eval-issue-121099.rs:11:31
+   |
+LL | global_asm!("/* {} */", const 1 / 0);
+   |                               ^^^^^ attempt to divide `1_i32` by zero
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.