Fix ICE in OUT_OF_BOUNDS_INDEXING
with ranges
This commit is contained in:
parent
893d6e8bf2
commit
1546cc4798
2 changed files with 22 additions and 11 deletions
|
@ -83,7 +83,7 @@ impl LateLintPass for ArrayIndexing {
|
||||||
eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None)).map(|v| v.ok());
|
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 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,
|
utils::span_lint(cx,
|
||||||
OUT_OF_BOUNDS_INDEXING,
|
OUT_OF_BOUNDS_INDEXING,
|
||||||
e.span,
|
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
|
/// 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
|
|
||||||
fn to_const_range(start: Option<Option<ConstVal>>,
|
fn to_const_range(start: Option<Option<ConstVal>>,
|
||||||
end: Option<Option<ConstVal>>,
|
end: Option<Option<ConstVal>>,
|
||||||
limits: RangeLimits,
|
limits: RangeLimits,
|
||||||
array_size: ConstInt)
|
array_size: ConstInt)
|
||||||
-> Option<(ConstInt, ConstInt)> {
|
-> Option<(ConstInt, ConstInt)> {
|
||||||
let start = match start {
|
let start = match start {
|
||||||
Some(Some(ConstVal::Integral(x))) => x,
|
Some(Some(ConstVal::Integral(x))) => x,
|
||||||
|
@ -127,13 +124,13 @@ fn to_const_range(start: Option<Option<ConstVal>>,
|
||||||
let end = match end {
|
let end = match end {
|
||||||
Some(Some(ConstVal::Integral(x))) => {
|
Some(Some(ConstVal::Integral(x))) => {
|
||||||
if limits == RangeLimits::Closed {
|
if limits == RangeLimits::Closed {
|
||||||
x
|
(x + ConstInt::Infer(1)).expect("such a big array is not realistic")
|
||||||
} else {
|
} else {
|
||||||
(x - ConstInt::Infer(1)).expect("x > 0")
|
x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => return None,
|
Some(_) => return None,
|
||||||
None => (array_size - ConstInt::Infer(1)).expect("array_size > 0"),
|
None => array_size
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((start, end))
|
Some((start, end))
|
||||||
|
|
|
@ -16,6 +16,8 @@ fn main() {
|
||||||
&x[0...4]; //~ERROR: range is out of bounds
|
&x[0...4]; //~ERROR: range is out of bounds
|
||||||
&x[..];
|
&x[..];
|
||||||
&x[1..];
|
&x[1..];
|
||||||
|
&x[4..];
|
||||||
|
&x[5..]; //~ERROR: range is out of bounds
|
||||||
&x[..4];
|
&x[..4];
|
||||||
&x[..5]; //~ERROR: range is out of bounds
|
&x[..5]; //~ERROR: range is out of bounds
|
||||||
|
|
||||||
|
@ -24,4 +26,16 @@ fn main() {
|
||||||
&y[1..2]; //~ERROR: slicing may panic
|
&y[1..2]; //~ERROR: slicing may panic
|
||||||
&y[..];
|
&y[..];
|
||||||
&y[0...4]; //~ERROR: slicing may panic
|
&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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue