Skip to content

Commit

Permalink
Rollup merge of rust-lang#122691 - veera-sivarajan:bugfix-121099, r=A…
Browse files Browse the repository at this point in the history
…manieu

Fix ICE: `global_asm!()` Don't Panic When Unable to Evaluate Constant

Fixes rust-lang#121099

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`.

r? ``@Amanieu``
  • Loading branch information
matthiaskrgr authored Mar 18, 2024
2 parents befcfb7 + 97cc700 commit 60704dd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 17 deletions.
46 changes: 29 additions & 17 deletions compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/asm/fail-const-eval-issue-121099.rs
Original file line number Diff line number Diff line change
@@ -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]
15 changes: 15 additions & 0 deletions tests/ui/asm/fail-const-eval-issue-121099.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 60704dd

Please sign in to comment.