From 935842bf0a7b3401355ea5285f1b8c6646a242c4 Mon Sep 17 00:00:00 2001 From: Veera Date: Mon, 18 Mar 2024 11:17:27 -0400 Subject: [PATCH 1/3] Add tests --- tests/ui/asm/fail-const-eval-issue-121099.rs | 10 ++++++++++ tests/ui/asm/fail-const-eval-issue-121099.stderr | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/ui/asm/fail-const-eval-issue-121099.rs create mode 100644 tests/ui/asm/fail-const-eval-issue-121099.stderr 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 0000000000000..7ae4376cecfbf --- /dev/null +++ b/tests/ui/asm/fail-const-eval-issue-121099.rs @@ -0,0 +1,10 @@ +//@ build-fail +#![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 0000000000000..5d86c3a5f7bdd --- /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:8: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:10: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`. From 97cc7003ca23289d04e4111b81453e2584856f54 Mon Sep 17 00:00:00 2001 From: Veera Date: Mon, 18 Mar 2024 11:26:30 -0400 Subject: [PATCH 2/3] Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant A bit of an inelegant fix but given that the error is created only after call to `const_eval_poly()` and that the calling function cannot propagate the error anywhere else, the error has to be explicitly handled inside `mono_item.rs`. --- compiler/rustc_codegen_ssa/src/mono_item.rs | 46 ++++++++++++-------- tests/ui/asm/fail-const-eval-issue-121099.rs | 2 +- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 7b7cdae0ed61a..df564f705bc73 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 index 7ae4376cecfbf..5bec3c8babb4e 100644 --- a/tests/ui/asm/fail-const-eval-issue-121099.rs +++ b/tests/ui/asm/fail-const-eval-issue-121099.rs @@ -1,4 +1,4 @@ -//@ build-fail +//@ build-fail #![feature(asm_const)] use std::arch::global_asm; From 394821060dac473390d723473217f0b2d630fc44 Mon Sep 17 00:00:00 2001 From: Veera Date: Mon, 18 Mar 2024 22:33:04 -0400 Subject: [PATCH 3/3] Update test with `//@ needs-asm-support` --- tests/ui/asm/fail-const-eval-issue-121099.rs | 1 + tests/ui/asm/fail-const-eval-issue-121099.stderr | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ui/asm/fail-const-eval-issue-121099.rs b/tests/ui/asm/fail-const-eval-issue-121099.rs index 5bec3c8babb4e..bed6fc9b39f9d 100644 --- a/tests/ui/asm/fail-const-eval-issue-121099.rs +++ b/tests/ui/asm/fail-const-eval-issue-121099.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ needs-asm-support #![feature(asm_const)] use std::arch::global_asm; diff --git a/tests/ui/asm/fail-const-eval-issue-121099.stderr b/tests/ui/asm/fail-const-eval-issue-121099.stderr index 5d86c3a5f7bdd..51d283218d227 100644 --- a/tests/ui/asm/fail-const-eval-issue-121099.stderr +++ b/tests/ui/asm/fail-const-eval-issue-121099.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/fail-const-eval-issue-121099.rs:8:31 + --> $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:10:31 + --> $DIR/fail-const-eval-issue-121099.rs:11:31 | LL | global_asm!("/* {} */", const 1 / 0); | ^^^^^ attempt to divide `1_i32` by zero