OUT_OF_BOUNDS_INDEXING fix #3102 false negative
This commit is contained in:
parent
601cc9d2c5
commit
0f3345e8b2
|
@ -111,17 +111,43 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
||||||
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
|
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
|
||||||
if let ty::Array(_, s) = ty.sty {
|
if let ty::Array(_, s) = ty.sty {
|
||||||
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
|
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
|
||||||
// Index is a constant range.
|
|
||||||
if let Some((start, end)) = to_const_range(cx, range, size) {
|
match to_const_range(cx, range, size) {
|
||||||
if start > size || end > size {
|
(None, None) => {},
|
||||||
utils::span_lint(
|
(Some(start), None) => {
|
||||||
cx,
|
if start > size {
|
||||||
OUT_OF_BOUNDS_INDEXING,
|
utils::span_lint(
|
||||||
expr.span,
|
cx,
|
||||||
"range is out of bounds",
|
OUT_OF_BOUNDS_INDEXING,
|
||||||
);
|
expr.span,
|
||||||
}
|
"range is out of bounds",
|
||||||
return;
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(None, Some(end)) => {
|
||||||
|
if end > size {
|
||||||
|
utils::span_lint(
|
||||||
|
cx,
|
||||||
|
OUT_OF_BOUNDS_INDEXING,
|
||||||
|
expr.span,
|
||||||
|
"range is out of bounds",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(Some(start), Some(end)) => {
|
||||||
|
if start > size || end > size {
|
||||||
|
utils::span_lint(
|
||||||
|
cx,
|
||||||
|
OUT_OF_BOUNDS_INDEXING,
|
||||||
|
expr.span,
|
||||||
|
"range is out of bounds",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// early return because both start and end are constant
|
||||||
|
return;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,20 +187,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an option containing a tuple with the start and end (exclusive) of
|
/// Returns a tuple of options with the start and end (exclusive) values of
|
||||||
/// the range.
|
/// the range. If the start or end is not constant, None is returned.
|
||||||
fn to_const_range<'a, 'tcx>(
|
fn to_const_range<'a, 'tcx>(
|
||||||
cx: &LateContext<'a, 'tcx>,
|
cx: &LateContext<'a, 'tcx>,
|
||||||
range: Range<'_>,
|
range: Range<'_>,
|
||||||
array_size: u128,
|
array_size: u128,
|
||||||
) -> Option<(u128, u128)> {
|
) -> (Option<u128>, Option<u128>) {
|
||||||
let s = range
|
let s = range
|
||||||
.start
|
.start
|
||||||
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
|
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
|
||||||
let start = match s {
|
let start = match s {
|
||||||
Some(Some(Constant::Int(x))) => x,
|
Some(Some(Constant::Int(x))) => Some(x),
|
||||||
Some(_) => return None,
|
Some(_) => None,
|
||||||
None => 0,
|
None => Some(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let e = range
|
let e = range
|
||||||
|
@ -182,13 +208,13 @@ fn to_const_range<'a, 'tcx>(
|
||||||
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
|
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
|
||||||
let end = match e {
|
let end = match e {
|
||||||
Some(Some(Constant::Int(x))) => if range.limits == RangeLimits::Closed {
|
Some(Some(Constant::Int(x))) => if range.limits == RangeLimits::Closed {
|
||||||
x + 1
|
Some(x + 1)
|
||||||
} else {
|
} else {
|
||||||
x
|
Some(x)
|
||||||
},
|
},
|
||||||
Some(_) => return None,
|
Some(_) => None,
|
||||||
None => array_size,
|
None => Some(array_size),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((start, end))
|
(start, end)
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,4 +91,9 @@ fn main() {
|
||||||
x[M]; // Ok, should not produce stderr.
|
x[M]; // Ok, should not produce stderr.
|
||||||
v[N];
|
v[N];
|
||||||
v[M];
|
v[M];
|
||||||
|
|
||||||
|
// issue 3102
|
||||||
|
let num = 1;
|
||||||
|
&x[num..10]; // should trigger out of bounds error
|
||||||
|
&x[10..num]; // should trigger out of bounds error
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,5 +267,17 @@ error: indexing may panic.
|
||||||
|
|
|
|
||||||
= help: Consider using `.get(n)` or `.get_mut(n)` instead
|
= help: Consider using `.get(n)` or `.get_mut(n)` instead
|
||||||
|
|
||||||
error: aborting due to 37 previous errors
|
error: range is out of bounds
|
||||||
|
--> $DIR/indexing_slicing.rs:97:6
|
||||||
|
|
|
||||||
|
97 | &x[num..10]; // should trigger out of bounds error
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: range is out of bounds
|
||||||
|
--> $DIR/indexing_slicing.rs:98:6
|
||||||
|
|
|
||||||
|
98 | &x[10..num]; // should trigger out of bounds error
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 39 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue