Skip to content

Commit 3853da7

Browse files
authored
Rollup merge of #69850 - RalfJung:panic-bounds-check, r=eddyb
panic_bounds_check: use caller_location, like PanicFnLangItem The `PanicFnLangItem` got switched to using `#[caller_location]` at some point, but `PanicBoundsCheckFnLangItem` was kept in the old style. For consistency, switch that one over to use `#[caller_location]` as well. This is also helpful for Miri as it means the `assert_panic` machine hook never needs to know the current `Span`.
2 parents 080d413 + 0b2329d commit 3853da7

File tree

7 files changed

+55
-7
lines changed

7 files changed

+55
-7
lines changed

src/libcore/macros/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(bootstrap)]
12
#[doc(include = "panic.md")]
23
#[macro_export]
34
#[allow_internal_unstable(core_panic, track_caller)]
@@ -20,6 +21,26 @@ macro_rules! panic {
2021
);
2122
}
2223

24+
#[cfg(not(bootstrap))]
25+
#[doc(include = "panic.md")]
26+
#[macro_export]
27+
#[allow_internal_unstable(core_panic, track_caller)]
28+
#[stable(feature = "core", since = "1.6.0")]
29+
macro_rules! panic {
30+
() => (
31+
$crate::panic!("explicit panic")
32+
);
33+
($msg:expr) => (
34+
$crate::panicking::panic($msg)
35+
);
36+
($msg:expr,) => (
37+
$crate::panic!($msg)
38+
);
39+
($fmt:expr, $($arg:tt)+) => (
40+
$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
41+
);
42+
}
43+
2344
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
2445
///
2546
/// On panic, this macro will print the values of the expressions with their

src/libcore/panicking.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use crate::fmt;
3333
use crate::panic::{Location, PanicInfo};
3434

35+
/// The underlying implementation of libcore's `panic!` macro when no formatting is used.
3536
#[cold]
3637
// never inline unless panic_immediate_abort to avoid code
3738
// bloat at the call sites as much as possible
@@ -49,9 +50,28 @@ pub fn panic(expr: &str) -> ! {
4950
// truncation and padding (even though none is used here). Using
5051
// Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
5152
// output binary, saving up to a few kilobytes.
52-
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), Location::caller())
53+
#[cfg(not(bootstrap))]
54+
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]));
55+
#[cfg(bootstrap)]
56+
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), Location::caller());
5357
}
5458

59+
#[cfg(not(bootstrap))]
60+
#[cold]
61+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
62+
#[track_caller]
63+
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
64+
fn panic_bounds_check(index: usize, len: usize) -> ! {
65+
if cfg!(feature = "panic_immediate_abort") {
66+
unsafe { super::intrinsics::abort() }
67+
}
68+
69+
panic!("index out of bounds: the len is {} but the index is {}", len, index)
70+
}
71+
72+
// For bootstrap, we need a variant with the old argument order, and a corresponding
73+
// `panic_fmt`.
74+
#[cfg(bootstrap)]
5575
#[cold]
5676
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
5777
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
@@ -66,10 +86,12 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
6686
)
6787
}
6888

89+
/// The underlying implementation of libcore's `panic!` macro when formatting is used.
6990
#[cold]
7091
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
7192
#[cfg_attr(feature = "panic_immediate_abort", inline)]
72-
pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
93+
#[cfg_attr(not(bootstrap), track_caller)]
94+
pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
7395
if cfg!(feature = "panic_immediate_abort") {
7496
unsafe { super::intrinsics::abort() }
7597
}
@@ -81,6 +103,10 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
81103
fn panic_impl(pi: &PanicInfo<'_>) -> !;
82104
}
83105

106+
#[cfg(bootstrap)]
84107
let pi = PanicInfo::internal_constructor(Some(&fmt), location);
108+
#[cfg(not(bootstrap))]
109+
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller());
110+
85111
unsafe { panic_impl(&pi) }
86112
}

src/librustc_codegen_ssa/mir/block.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
415415
AssertKind::BoundsCheck { ref len, ref index } => {
416416
let len = self.codegen_operand(&mut bx, len).immediate();
417417
let index = self.codegen_operand(&mut bx, index).immediate();
418-
(lang_items::PanicBoundsCheckFnLangItem, vec![location, index, len])
418+
// It's `fn panic_bounds_check(index: usize, len: usize)`,
419+
// and `#[track_caller]` adds an implicit third argument.
420+
(lang_items::PanicBoundsCheckFnLangItem, vec![index, len, location])
419421
}
420422
_ => {
421423
let msg_str = Symbol::intern(msg.description());
422424
let msg = bx.const_str(msg_str);
425+
// It's `pub fn panic(expr: &str)`, with the wide reference being passed
426+
// as two arguments, and `#[track_caller]` adds an implicit third argument.
423427
(lang_items::PanicFnLangItem, vec![msg.0, msg.1, location])
424428
}
425429
};

src/librustc_mir/const_eval/machine.rs

-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
280280

281281
fn assert_panic(
282282
ecx: &mut InterpCx<'mir, 'tcx, Self>,
283-
_span: Span,
284283
msg: &AssertMessage<'tcx>,
285284
_unwind: Option<mir::BasicBlock>,
286285
) -> InterpResult<'tcx> {

src/librustc_mir/interpret/machine.rs

-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
165165
/// Called to evaluate `Assert` MIR terminators that trigger a panic.
166166
fn assert_panic(
167167
ecx: &mut InterpCx<'mir, 'tcx, Self>,
168-
span: Span,
169168
msg: &mir::AssertMessage<'tcx>,
170169
unwind: Option<mir::BasicBlock>,
171170
) -> InterpResult<'tcx>;

src/librustc_mir/interpret/terminator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9595
if expected == cond_val {
9696
self.go_to_block(target);
9797
} else {
98-
M::assert_panic(self, terminator.source_info.span, msg, cleanup)?;
98+
M::assert_panic(self, msg, cleanup)?;
9999
}
100100
}
101101

src/librustc_mir/transform/const_prop.rs

-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
197197

198198
fn assert_panic(
199199
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
200-
_span: Span,
201200
_msg: &rustc::mir::AssertMessage<'tcx>,
202201
_unwind: Option<rustc::mir::BasicBlock>,
203202
) -> InterpResult<'tcx> {

0 commit comments

Comments
 (0)