Skip to content

Miri core engine: use throw_ub instead of throw_panic #66927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 7, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
@@ -371,6 +371,14 @@ pub enum UndefinedBehaviorInfo {
Unreachable,
/// An enum discriminant was set to a value which was outside the range of valid values.
InvalidDiscriminant(ScalarMaybeUndef),
/// A slice/array index projection went out-of-bounds.
BoundsCheckFailed { len: u64, index: u64 },
/// Something was divided by 0 (x / 0).
DivisionByZero,
/// Something was "remainded" by 0 (x % 0).
RemainderByZero,
/// Overflowing inbounds pointer arithmetic.
PointerArithOverflow,
}

impl fmt::Debug for UndefinedBehaviorInfo {
@@ -380,9 +388,18 @@ impl fmt::Debug for UndefinedBehaviorInfo {
Ub(msg) | UbExperimental(msg) =>
write!(f, "{}", msg),
Unreachable =>
write!(f, "entered unreachable code"),
write!(f, "entering unreachable code"),
InvalidDiscriminant(val) =>
write!(f, "encountered invalid enum discriminant {}", val),
write!(f, "encountering invalid enum discriminant {}", val),
BoundsCheckFailed { ref len, ref index } =>
write!(f, "indexing out of bounds: the len is {:?} but the index is {:?}",
len, index),
DivisionByZero =>
write!(f, "dividing by zero"),
RemainderByZero =>
write!(f, "calculating the remainder with a divisor of zero"),
PointerArithOverflow =>
write!(f, "overflowing in-bounds pointer arithmetic"),
}
}
}
5 changes: 2 additions & 3 deletions src/librustc/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{AllocId, InterpResult};

use crate::mir;
use crate::ty::layout::{self, HasDataLayout, Size};

use rustc_macros::HashStable;
@@ -88,13 +87,13 @@ pub trait PointerArithmetic: layout::HasDataLayout {
#[inline]
fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
let (res, over) = self.overflowing_offset(val, i);
if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
if over { throw_ub!(PointerArithOverflow) } else { Ok(res) }
}

#[inline]
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
if over { throw_ub!(PointerArithOverflow) } else { Ok(res) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, so this is now specific enough to be equivalent to LLVM "inbounds GEP" overflowing, nice!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is the intention.

}
}

8 changes: 4 additions & 4 deletions src/librustc_mir/interpret/operator.rs
Original file line number Diff line number Diff line change
@@ -177,8 +177,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok((Scalar::from_bool(op(&l, &r)), false, self.tcx.types.bool));
}
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
Div if r == 0 => throw_panic!(DivisionByZero),
Rem if r == 0 => throw_panic!(RemainderByZero),
Div if r == 0 => throw_ub!(DivisionByZero),
Rem if r == 0 => throw_ub!(RemainderByZero),
Div => Some(i128::overflowing_div),
Rem => Some(i128::overflowing_rem),
Add => Some(i128::overflowing_add),
@@ -234,8 +234,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Add => u128::overflowing_add,
Sub => u128::overflowing_sub,
Mul => u128::overflowing_mul,
Div if r == 0 => throw_panic!(DivisionByZero),
Rem if r == 0 => throw_panic!(RemainderByZero),
Div if r == 0 => throw_ub!(DivisionByZero),
Rem if r == 0 => throw_ub!(RemainderByZero),
Div => u128::overflowing_div,
Rem => u128::overflowing_rem,
_ => bug!(),
6 changes: 2 additions & 4 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
@@ -384,10 +384,8 @@ where
layout::FieldPlacement::Array { stride, .. } => {
let len = base.len(self)?;
if field >= len {
// This can be violated because the index (field) can be a runtime value
// provided by the user.
debug!("tried to access element {} of array/slice with length {}", field, len);
throw_panic!(BoundsCheck { len, index: field });
// This can only be reached in ConstProp and non-rustc-MIR.
throw_ub!(BoundsCheckFailed { len, index: field });
}
stride * field
}
1 change: 0 additions & 1 deletion src/test/compile-fail/consts/const-err3.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ fn main() {
//~^ ERROR const_err
let _e = [5u8][1];
//~^ ERROR const_err
//~| ERROR this expression will panic at runtime
black_box(b);
black_box(c);
black_box(d);
2 changes: 1 addition & 1 deletion src/test/ui/consts/array-literal-index-oob.stderr
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ error: reaching this expression at runtime will panic or abort
LL | &{[1, 2, 3][4]};
| --^^^^^^^^^^^^-
| |
| index out of bounds: the len is 3 but the index is 4
| indexing out of bounds: the len is 3 but the index is 4

error: aborting due to 2 previous errors

1 change: 0 additions & 1 deletion src/test/ui/consts/const-err2.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ fn main() {
//~^ ERROR const_err
let _e = [5u8][1];
//~^ ERROR index out of bounds
//~| ERROR this expression will panic at runtime
black_box(a);
black_box(b);
black_box(c);
8 changes: 1 addition & 7 deletions src/test/ui/consts/const-err2.stderr
Original file line number Diff line number Diff line change
@@ -34,11 +34,5 @@ error: index out of bounds: the len is 1 but the index is 1
LL | let _e = [5u8][1];
| ^^^^^^^^

error: this expression will panic at runtime
--> $DIR/const-err2.rs:24:14
|
LL | let _e = [5u8][1];
| ^^^^^^^^ index out of bounds: the len is 1 but the index is 1

error: aborting due to 6 previous errors
error: aborting due to 5 previous errors

1 change: 0 additions & 1 deletion src/test/ui/consts/const-err3.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ fn main() {
//~^ ERROR const_err
let _e = [5u8][1];
//~^ ERROR const_err
//~| ERROR this expression will panic at runtime
black_box(a);
black_box(b);
black_box(c);
8 changes: 1 addition & 7 deletions src/test/ui/consts/const-err3.stderr
Original file line number Diff line number Diff line change
@@ -34,11 +34,5 @@ error: index out of bounds: the len is 1 but the index is 1
LL | let _e = [5u8][1];
| ^^^^^^^^

error: this expression will panic at runtime
--> $DIR/const-err3.rs:24:14
|
LL | let _e = [5u8][1];
| ^^^^^^^^ index out of bounds: the len is 1 but the index is 1

error: aborting due to 6 previous errors
error: aborting due to 5 previous errors

6 changes: 2 additions & 4 deletions src/test/ui/consts/const-eval/promoted_errors.rs
Original file line number Diff line number Diff line change
@@ -8,14 +8,12 @@ fn main() {
//~^ ERROR const_err
println!("{}", 1/(1-1));
//~^ ERROR attempt to divide by zero [const_err]
//~| ERROR reaching this expression at runtime will panic or abort [const_err]
//~| ERROR const_err
let _x = 1/(1-1);
//~^ ERROR const_err
//~| ERROR const_err
println!("{}", 1/(false as u32));
//~^ ERROR attempt to divide by zero [const_err]
//~| ERROR reaching this expression at runtime will panic or abort [const_err]
//~| ERROR const_err
let _x = 1/(false as u32);
//~^ ERROR const_err
//~| ERROR const_err
}
24 changes: 6 additions & 18 deletions src/test/ui/consts/const-eval/promoted_errors.stderr
Original file line number Diff line number Diff line change
@@ -20,43 +20,31 @@ error: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors.rs:9:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^ attempt to divide by zero
| ^^^^^^^ dividing by zero

error: attempt to divide by zero
--> $DIR/promoted_errors.rs:12:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^

error: this expression will panic at runtime
--> $DIR/promoted_errors.rs:12:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^ attempt to divide by zero

error: attempt to divide by zero
--> $DIR/promoted_errors.rs:15:20
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^

error: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors.rs:15:20
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
| ^^^^^^^^^^^^^^^^ dividing by zero

error: attempt to divide by zero
--> $DIR/promoted_errors.rs:18:14
--> $DIR/promoted_errors.rs:17:14
|
LL | let _x = 1/(false as u32);
| ^^^^^^^^^^^^^^^^

error: this expression will panic at runtime
--> $DIR/promoted_errors.rs:18:14
|
LL | let _x = 1/(false as u32);
| ^^^^^^^^^^^^^^^^ attempt to divide by zero

error: aborting due to 9 previous errors
error: aborting due to 7 previous errors

6 changes: 2 additions & 4 deletions src/test/ui/consts/const-eval/promoted_errors2.rs
Original file line number Diff line number Diff line change
@@ -9,14 +9,12 @@ fn main() {
//~^ ERROR attempt to subtract with overflow
println!("{}", 1/(1-1));
//~^ ERROR attempt to divide by zero [const_err]
//~| ERROR reaching this expression at runtime will panic or abort [const_err]
//~| ERROR const_err
let _x = 1/(1-1);
//~^ ERROR const_err
//~| ERROR const_err
println!("{}", 1/(false as u32));
//~^ ERROR attempt to divide by zero [const_err]
//~| ERROR reaching this expression at runtime will panic or abort [const_err]
//~| ERROR const_err
let _x = 1/(false as u32);
//~^ ERROR const_err
//~| ERROR const_err
}
24 changes: 6 additions & 18 deletions src/test/ui/consts/const-eval/promoted_errors2.stderr
Original file line number Diff line number Diff line change
@@ -26,43 +26,31 @@ error: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors2.rs:10:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^ attempt to divide by zero
| ^^^^^^^ dividing by zero

error: attempt to divide by zero
--> $DIR/promoted_errors2.rs:13:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^

error: this expression will panic at runtime
--> $DIR/promoted_errors2.rs:13:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^ attempt to divide by zero

error: attempt to divide by zero
--> $DIR/promoted_errors2.rs:16:20
--> $DIR/promoted_errors2.rs:15:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^

error: reaching this expression at runtime will panic or abort
--> $DIR/promoted_errors2.rs:16:20
--> $DIR/promoted_errors2.rs:15:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^ attempt to divide by zero
| ^^^^^^^^^^^^^^^^ dividing by zero

error: attempt to divide by zero
--> $DIR/promoted_errors2.rs:19:14
--> $DIR/promoted_errors2.rs:18:14
|
LL | let _x = 1/(false as u32);
| ^^^^^^^^^^^^^^^^

error: this expression will panic at runtime
--> $DIR/promoted_errors2.rs:19:14
|
LL | let _x = 1/(false as u32);
| ^^^^^^^^^^^^^^^^ attempt to divide by zero

error: aborting due to 10 previous errors
error: aborting due to 8 previous errors

1 change: 0 additions & 1 deletion src/test/ui/consts/const-prop-ice.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fn main() {
[0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
//~| ERROR this expression will panic at runtime
}
8 changes: 1 addition & 7 deletions src/test/ui/consts/const-prop-ice.stderr
Original file line number Diff line number Diff line change
@@ -6,11 +6,5 @@ LL | [0; 3][3u64 as usize];
|
= note: `#[deny(const_err)]` on by default

error: this expression will panic at runtime
--> $DIR/const-prop-ice.rs:2:5
|
LL | [0; 3][3u64 as usize];
| ^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 3 but the index is 3

error: aborting due to 2 previous errors
error: aborting due to previous error

2 changes: 0 additions & 2 deletions src/test/ui/issues/issue-54348.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
fn main() {
[1][0u64 as usize];
[1][1.5 as usize]; //~ ERROR index out of bounds
//~| ERROR this expression will panic at runtime
[1][1u64 as usize]; //~ ERROR index out of bounds
//~| ERROR this expression will panic at runtime
}
16 changes: 2 additions & 14 deletions src/test/ui/issues/issue-54348.stderr
Original file line number Diff line number Diff line change
@@ -6,23 +6,11 @@ LL | [1][1.5 as usize];
|
= note: `#[deny(const_err)]` on by default

error: this expression will panic at runtime
--> $DIR/issue-54348.rs:3:5
|
LL | [1][1.5 as usize];
| ^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1

error: index out of bounds: the len is 1 but the index is 1
--> $DIR/issue-54348.rs:5:5
--> $DIR/issue-54348.rs:4:5
|
LL | [1][1u64 as usize];
| ^^^^^^^^^^^^^^^^^^

error: this expression will panic at runtime
--> $DIR/issue-54348.rs:5:5
|
LL | [1][1u64 as usize];
| ^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1

error: aborting due to 4 previous errors
error: aborting due to 2 previous errors

10 changes: 0 additions & 10 deletions src/test/ui/issues/issue-8460-const.rs
Original file line number Diff line number Diff line change
@@ -23,19 +23,14 @@ fn main() {
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
//~^ ERROR attempt to divide by zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
//~^ ERROR attempt to divide by zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
//~^ ERROR attempt to divide by zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
//~^ ERROR attempt to divide by zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
//~^ ERROR attempt to divide by zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with overflow
//~| ERROR this expression will panic at runtime
@@ -53,17 +48,12 @@ fn main() {
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with a divisor of zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with a divisor of zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with a divisor of zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with a divisor of zero
//~| ERROR this expression will panic at runtime
assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
//~^ ERROR attempt to calculate the remainder with a divisor of zero
//~| ERROR this expression will panic at runtime
}
Loading