about summary refs log tree commit diff
diff options
context:
space:
mode:
authorcocodery <cocodery@outlook.com>2023-12-22 20:17:43 +0800
committercocodery <cocodery@outlook.com>2023-12-22 20:17:43 +0800
commitd020196dc096d255caa72f04a6da5e8e41d2b717 (patch)
tree9660c4d489628590f58980d8bb1a2662296bfc60
parent7e650b761006b9dfb5b26a05c2f725a06e9cb14d (diff)
downloadrust-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.rs18
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;
                     }