Fix ICE in OUT_OF_BOUNDS_INDEXING with ranges

This commit is contained in:
mcarton 2016-03-14 21:48:24 +01:00
parent 893d6e8bf2
commit 1546cc4798
2 changed files with 22 additions and 11 deletions

View File

@ -83,7 +83,7 @@ impl LateLintPass for ArrayIndexing {
eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None)).map(|v| v.ok());
if let Some((start, end)) = to_const_range(start, end, range.limits, size) {
if start >= size || end >= size {
if start > size || end > size {
utils::span_lint(cx,
OUT_OF_BOUNDS_INDEXING,
e.span,
@ -109,14 +109,11 @@ impl LateLintPass for ArrayIndexing {
}
}
/// Returns an option containing a tuple with the start and end (exclusive) of the range
///
/// Note: we assume the start and the end of the range are unsigned, since array slicing
/// works only on usize
/// Returns an option containing a tuple with the start and end (exclusive) of the range.
fn to_const_range(start: Option<Option<ConstVal>>,
end: Option<Option<ConstVal>>,
limits: RangeLimits,
array_size: ConstInt)
end: Option<Option<ConstVal>>,
limits: RangeLimits,
array_size: ConstInt)
-> Option<(ConstInt, ConstInt)> {
let start = match start {
Some(Some(ConstVal::Integral(x))) => x,
@ -127,13 +124,13 @@ fn to_const_range(start: Option<Option<ConstVal>>,
let end = match end {
Some(Some(ConstVal::Integral(x))) => {
if limits == RangeLimits::Closed {
x
(x + ConstInt::Infer(1)).expect("such a big array is not realistic")
} else {
(x - ConstInt::Infer(1)).expect("x > 0")
x
}
}
Some(_) => return None,
None => (array_size - ConstInt::Infer(1)).expect("array_size > 0"),
None => array_size
};
Some((start, end))

View File

@ -16,6 +16,8 @@ fn main() {
&x[0...4]; //~ERROR: range is out of bounds
&x[..];
&x[1..];
&x[4..];
&x[5..]; //~ERROR: range is out of bounds
&x[..4];
&x[..5]; //~ERROR: range is out of bounds
@ -24,4 +26,16 @@ fn main() {
&y[1..2]; //~ERROR: slicing may panic
&y[..];
&y[0...4]; //~ERROR: slicing may panic
let empty: [i8; 0] = [];
empty[0]; //~ERROR: const index is out of bounds
&empty[1..5]; //~ERROR: range is out of bounds
&empty[0...4]; //~ERROR: range is out of bounds
&empty[..];
&empty[0..];
&empty[0..0];
&empty[0...0]; //~ERROR: range is out of bounds
&empty[..0];
&empty[1..]; //~ERROR: range is out of bounds
&empty[..4]; //~ERROR: range is out of bounds
}