Skip to content

Commit b4a6a4c

Browse files
committed
codegen: decode panic_bounds_check debug-printf args
1 parent facad7d commit b4a6a4c

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

crates/rustc_codegen_spirv/src/builder/format_args_decompiler.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use either::Either;
88
use itertools::Itertools;
99
use rspirv::dr::Operand;
1010
use rspirv::spirv::{Op, Word};
11-
use rustc_abi::BackendRepr;
11+
use rustc_abi::{Align, BackendRepr};
1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_middle::ty::Ty;
1414
use rustc_middle::ty::layout::LayoutOf;
@@ -17,6 +17,8 @@ use smallvec::SmallVec;
1717
use std::borrow::Cow;
1818
use std::cell::Cell;
1919

20+
use crate::maybe_pqp_cg_ssa::traits::BuilderMethods;
21+
2022
// HACK(eddyb) Rust 2021 `panic!` always uses `format_args!`, even
2123
// in the simple case that used to pass a `&str` constant, which
2224
// would not remain reachable in the SPIR-V - but `format_args!` is
@@ -233,6 +235,42 @@ impl<'tcx> DecodedFormatArgs<'tcx> {
233235
_ => None,
234236
}
235237
};
238+
let mut spill_value_to_local = |value: SpirvValue| {
239+
let ptr = builder.typed_alloca(value.ty, Align::ONE);
240+
builder.store(value, ptr, Align::ONE);
241+
match ptr.kind {
242+
SpirvValueKind::Def(id) => Some(id),
243+
_ => None,
244+
}
245+
};
246+
247+
if panic_def_id.is_some_and(|def_id| {
248+
cx.tcx.def_path_str(def_id) == "core::panicking::panic_bounds_check"
249+
}) && args.len() >= 2
250+
{
251+
let index = args[0].clone();
252+
let len = args[1].clone();
253+
if let (Some(len_ref_id), Some(index_ref_id)) =
254+
(spill_value_to_local(len), spill_value_to_local(index))
255+
{
256+
decoded_format_args.const_pieces = Some(
257+
[
258+
"index out of bounds: the len is ".into(),
259+
" but the index is ".into(),
260+
String::new(),
261+
]
262+
.into_iter()
263+
.collect(),
264+
);
265+
decoded_format_args.ref_arg_ids_with_ty_and_spec = [
266+
(len_ref_id, cx.tcx.types.usize, ' '),
267+
(index_ref_id, cx.tcx.types.usize, ' '),
268+
]
269+
.into_iter()
270+
.collect();
271+
return Ok(decoded_format_args);
272+
}
273+
}
236274

237275
// HACK(eddyb) `panic_explicit` doesn't take any regular arguments,
238276
// only an (implicit) `&'static panic::Location<'static>`.

tests/compiletests/ui/dis/panic_builtin_bounds_check.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ OpExtension "SPV_KHR_non_semantic_info"
44
OpMemoryModel Logical Simple
55
OpEntryPoint Fragment %2 "main"
66
OpExecutionMode %2 OriginUpperLeft
7-
%3 = OpString "/n[Rust panicked at $DIR/panic_builtin_bounds_check.rs:27:5]/n <unknown message>/n in main()/n"
7+
%3 = OpString "/n[Rust panicked at $DIR/panic_builtin_bounds_check.rs:27:5]/n index out of bounds: the len is %u but the index is %u/n in main()/n"
88
%4 = OpString "$DIR/panic_builtin_bounds_check.rs"
99
OpDecorate %5 ArrayStride 4
1010
%6 = OpTypeVoid
@@ -43,7 +43,7 @@ OpBranchConditional %27 %29 %30
4343
OpBranch %28
4444
%30 = OpLabel
4545
OpLine %4 27 4
46-
%31 = OpExtInst %6 %1 1 %3
46+
%31 = OpExtInst %6 %1 1 %3 %9 %17
4747
OpNoLine
4848
OpReturn
4949
%28 = OpLabel

0 commit comments

Comments
 (0)