rustc_const_eval: track the length and index in IndexOutOfBounds.
This commit is contained in:
parent
afc598e075
commit
1447fbf183
@ -390,7 +390,7 @@ pub enum ErrKind {
|
||||
IndexedNonVec,
|
||||
IndexNegative,
|
||||
IndexNotInt,
|
||||
IndexOutOfBounds,
|
||||
IndexOutOfBounds { len: u64, index: u64 },
|
||||
RepeatCountNotNatural,
|
||||
RepeatCountNotInt,
|
||||
|
||||
@ -441,7 +441,10 @@ impl ConstEvalErr {
|
||||
IndexedNonVec => "indexing is only supported for arrays".into_cow(),
|
||||
IndexNegative => "indices must be non-negative integers".into_cow(),
|
||||
IndexNotInt => "indices must be integers".into_cow(),
|
||||
IndexOutOfBounds => "array index out of bounds".into_cow(),
|
||||
IndexOutOfBounds { len, index } => {
|
||||
format!("index out of bounds: the len is {} but the index is {}",
|
||||
len, index).into_cow()
|
||||
}
|
||||
RepeatCountNotNatural => "repeat count must be a natural number".into_cow(),
|
||||
RepeatCountNotInt => "repeat count must be integers".into_cow(),
|
||||
|
||||
@ -835,7 +838,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
};
|
||||
assert_eq!(idx as usize as u64, idx);
|
||||
match arr {
|
||||
Array(_, n) if idx >= n => signal!(e, IndexOutOfBounds),
|
||||
Array(_, n) if idx >= n => {
|
||||
signal!(e, IndexOutOfBounds { len: n, index: idx })
|
||||
}
|
||||
Array(v, n) => if let hir::ExprVec(ref v) = tcx.map.expect_expr(v).node {
|
||||
assert_eq!(n as usize as u64, n);
|
||||
eval_const_expr_partial(tcx, &v[idx as usize], ty_hint, fn_args)?
|
||||
@ -843,7 +848,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
bug!()
|
||||
},
|
||||
|
||||
Repeat(_, n) if idx >= n => signal!(e, IndexOutOfBounds),
|
||||
Repeat(_, n) if idx >= n => {
|
||||
signal!(e, IndexOutOfBounds { len: n, index: idx })
|
||||
}
|
||||
Repeat(elem, _) => eval_const_expr_partial(
|
||||
tcx,
|
||||
&tcx.map.expect_expr(elem),
|
||||
@ -851,7 +858,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn_args,
|
||||
)?,
|
||||
|
||||
ByteStr(ref data) if idx >= data.len() as u64 => signal!(e, IndexOutOfBounds),
|
||||
ByteStr(ref data) if idx >= data.len() as u64 => {
|
||||
signal!(e, IndexOutOfBounds { len: data.len() as u64, index: idx })
|
||||
}
|
||||
ByteStr(data) => {
|
||||
Integral(U8(data[idx as usize]))
|
||||
},
|
||||
|
@ -716,7 +716,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
if iv >= len {
|
||||
// FIXME #3170: report this earlier on in the const-eval
|
||||
// pass. Reporting here is a bit late.
|
||||
const_err(cx, e.span, Err(ErrKind::IndexOutOfBounds), trueconst)?;
|
||||
const_err(cx, e.span, Err(ErrKind::IndexOutOfBounds {
|
||||
len: len,
|
||||
index: iv
|
||||
}), trueconst)?;
|
||||
C_undef(val_ty(arr).element_type())
|
||||
} else {
|
||||
const_get_elt(arr, &[iv as c_uint])
|
||||
|
@ -298,8 +298,13 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
let cond_bool = common::const_to_uint(cond.llval) != 0;
|
||||
if cond_bool != expected {
|
||||
let err = match *msg {
|
||||
mir::AssertMessage::BoundsCheck {..} => {
|
||||
ErrKind::IndexOutOfBounds
|
||||
mir::AssertMessage::BoundsCheck { ref len, ref index } => {
|
||||
let len = self.const_operand(len, span)?;
|
||||
let index = self.const_operand(index, span)?;
|
||||
ErrKind::IndexOutOfBounds {
|
||||
len: common::const_to_uint(len.llval),
|
||||
index: common::const_to_uint(index.llval)
|
||||
}
|
||||
}
|
||||
mir::AssertMessage::Math(ref err) => {
|
||||
ErrKind::Math(err.clone())
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
const A: &'static [i32] = &[];
|
||||
const B: i32 = (&A)[1];
|
||||
//~^ ERROR: array index out of bounds
|
||||
//~^ ERROR index out of bounds: the len is 0 but the index is 1
|
||||
|
||||
fn main() {
|
||||
let _ = B;
|
||||
|
@ -9,7 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
const A: [i32; 0] = [];
|
||||
const B: i32 = A[1]; //~ ERROR: array index out of bounds
|
||||
const B: i32 = A[1];
|
||||
//~^ ERROR index out of bounds: the len is 0 but the index is 1
|
||||
|
||||
fn main() {
|
||||
let _ = B;
|
||||
|
@ -8,13 +8,15 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![feature(const_indexing)]
|
||||
|
||||
const FOO: [u32; 3] = [1, 2, 3];
|
||||
const BAR: u32 = FOO[5]; // no error, because the error below occurs before regular const eval
|
||||
|
||||
const BLUB: [u32; FOO[4]] = [5, 6];
|
||||
//~^ ERROR array length constant evaluation error: array index out of bounds [E0250]
|
||||
//~^ ERROR array length constant evaluation error: index out of bounds: the len is 3 but the index is 4 [E0250]
|
||||
|
||||
fn main() {
|
||||
let _ = BAR;
|
||||
|
@ -15,8 +15,10 @@ pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
|
||||
pub const B: u8 = 200u8 + 200u8; //~ ERROR attempted to add with overflow
|
||||
pub const C: u8 = 200u8 * 4; //~ ERROR attempted to multiply with overflow
|
||||
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overflow
|
||||
pub const E: u8 = [5u8][1]; //~ ERROR index out of bounds
|
||||
pub const E: u8 = [5u8][1];
|
||||
//~^ ERROR index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
fn main() {
|
||||
let _e = [6u8][1]; //~ ERROR: array index out of bounds
|
||||
let _e = [6u8][1];
|
||||
//~^ ERROR index out of bounds: the len is 1 but the index is 1
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ fn black_box<T>(_: T) {
|
||||
|
||||
// Make sure that the two uses get two errors.
|
||||
const FOO: u8 = [5u8][1];
|
||||
//~^ ERROR array index out of bounds
|
||||
//~^^ ERROR array index out of bounds
|
||||
//~^ ERROR 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
|
||||
|
||||
fn main() {
|
||||
let a = -std::i8::MIN;
|
||||
@ -34,7 +34,7 @@ fn main() {
|
||||
let d = 42u8 - (42u8 + 1);
|
||||
//~^ WARN attempted to subtract with overflow
|
||||
let _e = [5u8][1];
|
||||
//~^ WARN array index out of bounds
|
||||
//~^ WARN index out of bounds: the len is 1 but the index is 1
|
||||
black_box(a);
|
||||
black_box(b);
|
||||
black_box(c);
|
||||
|
@ -9,7 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
const FOO: &'static[u32] = &[1, 2, 3];
|
||||
const BAR: u32 = FOO[5]; //~ ERROR array index out of bounds
|
||||
const BAR: u32 = FOO[5];
|
||||
//~^ ERROR index out of bounds: the len is 3 but the index is 5
|
||||
|
||||
fn main() {
|
||||
let _ = BAR;
|
||||
|
Loading…
x
Reference in New Issue
Block a user