Skip to content

Commit 0f3345e

Browse files
committed
OUT_OF_BOUNDS_INDEXING fix #3102 false negative
1 parent 601cc9d commit 0f3345e

File tree

3 files changed

+66
-23
lines changed

3 files changed

+66
-23
lines changed

clippy_lints/src/indexing_slicing.rs

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,43 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
111111
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
112112
if let ty::Array(_, s) = ty.sty {
113113
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
114-
// Index is a constant range.
115-
if let Some((start, end)) = to_const_range(cx, range, size) {
116-
if start > size || end > size {
117-
utils::span_lint(
118-
cx,
119-
OUT_OF_BOUNDS_INDEXING,
120-
expr.span,
121-
"range is out of bounds",
122-
);
123-
}
124-
return;
114+
115+
match to_const_range(cx, range, size) {
116+
(None, None) => {},
117+
(Some(start), None) => {
118+
if start > size {
119+
utils::span_lint(
120+
cx,
121+
OUT_OF_BOUNDS_INDEXING,
122+
expr.span,
123+
"range is out of bounds",
124+
);
125+
return;
126+
}
127+
},
128+
(None, Some(end)) => {
129+
if end > size {
130+
utils::span_lint(
131+
cx,
132+
OUT_OF_BOUNDS_INDEXING,
133+
expr.span,
134+
"range is out of bounds",
135+
);
136+
return;
137+
}
138+
},
139+
(Some(start), Some(end)) => {
140+
if start > size || end > size {
141+
utils::span_lint(
142+
cx,
143+
OUT_OF_BOUNDS_INDEXING,
144+
expr.span,
145+
"range is out of bounds",
146+
);
147+
}
148+
// early return because both start and end are constant
149+
return;
150+
},
125151
}
126152
}
127153

@@ -161,34 +187,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
161187
}
162188
}
163189

164-
/// Returns an option containing a tuple with the start and end (exclusive) of
165-
/// the range.
190+
/// Returns a tuple of options with the start and end (exclusive) values of
191+
/// the range. If the start or end is not constant, None is returned.
166192
fn to_const_range<'a, 'tcx>(
167193
cx: &LateContext<'a, 'tcx>,
168194
range: Range<'_>,
169195
array_size: u128,
170-
) -> Option<(u128, u128)> {
196+
) -> (Option<u128>, Option<u128>) {
171197
let s = range
172198
.start
173199
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
174200
let start = match s {
175-
Some(Some(Constant::Int(x))) => x,
176-
Some(_) => return None,
177-
None => 0,
201+
Some(Some(Constant::Int(x))) => Some(x),
202+
Some(_) => None,
203+
None => Some(0),
178204
};
179205

180206
let e = range
181207
.end
182208
.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c));
183209
let end = match e {
184210
Some(Some(Constant::Int(x))) => if range.limits == RangeLimits::Closed {
185-
x + 1
211+
Some(x + 1)
186212
} else {
187-
x
213+
Some(x)
188214
},
189-
Some(_) => return None,
190-
None => array_size,
215+
Some(_) => None,
216+
None => Some(array_size),
191217
};
192218

193-
Some((start, end))
219+
(start, end)
194220
}

tests/ui/indexing_slicing.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,9 @@ fn main() {
9191
x[M]; // Ok, should not produce stderr.
9292
v[N];
9393
v[M];
94+
95+
// issue 3102
96+
let num = 1;
97+
&x[num..10]; // should trigger out of bounds error
98+
&x[10..num]; // should trigger out of bounds error
9499
}

tests/ui/indexing_slicing.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,5 +267,17 @@ error: indexing may panic.
267267
|
268268
= help: Consider using `.get(n)` or `.get_mut(n)` instead
269269

270-
error: aborting due to 37 previous errors
270+
error: range is out of bounds
271+
--> $DIR/indexing_slicing.rs:97:6
272+
|
273+
97 | &x[num..10]; // should trigger out of bounds error
274+
| ^^^^^^^^^^
275+
276+
error: range is out of bounds
277+
--> $DIR/indexing_slicing.rs:98:6
278+
|
279+
98 | &x[10..num]; // should trigger out of bounds error
280+
| ^^^^^^^^^^
281+
282+
error: aborting due to 39 previous errors
271283

0 commit comments

Comments
 (0)