diff options
| author | cocodery <cocodery@outlook.com> | 2023-12-22 20:17:43 +0800 |
|---|---|---|
| committer | cocodery <cocodery@outlook.com> | 2023-12-22 20:17:43 +0800 |
| commit | d020196dc096d255caa72f04a6da5e8e41d2b717 (patch) | |
| tree | 9660c4d489628590f58980d8bb1a2662296bfc60 | |
| parent | 7e650b761006b9dfb5b26a05c2f725a06e9cb14d (diff) | |
| download | rust-d020196dc096d255caa72f04a6da5e8e41d2b717.tar.gz rust-d020196dc096d255caa72f04a6da5e8e41d2b717.zip | |
Add check for illegal accessing known length array with a constant index
| -rw-r--r-- | clippy_lints/src/indexing_slicing.rs | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index 0ae03d101ab..391db0b0df7 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -170,7 +170,23 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { return; } // Index is a constant uint. - if constant(cx, cx.typeck_results(), index).is_some() { + if let Some(constant) = constant(cx, cx.typeck_results(), index) { + // only `usize` index is legal in rust array index + // leave other type to rustc + if let Constant::Int(off) = constant + && let ty::Uint(utype) = cx.typeck_results().expr_ty(index).kind() + && *utype == ty::UintTy::Usize + && let ty::Array(_, s) = ty.kind() + && let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) + { + // get constant offset and check whether it is in bounds + let off = usize::try_from(off).unwrap(); + let size = usize::try_from(size).unwrap(); + + if off >= size { + span_lint(cx, OUT_OF_BOUNDS_INDEXING, expr.span, "index is out of bounds"); + } + } // Let rustc's `const_err` lint handle constant `usize` indexing on arrays. return; } |
