[clang] [Wunsafe-buffer-usage] Fix false positive when const sized array is indexed by const evaluatable expressions (PR #119340)
Malavika Samak via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 13 08:02:16 PST 2025
https://github.com/malavikasamak updated https://github.com/llvm/llvm-project/pull/119340
>From ca068b2383b784d783a33f3678f6bb90a6544861 Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Tue, 10 Dec 2024 11:05:21 +0530
Subject: [PATCH] [Wunsafe-buffer-usage] Fix false positive when const sized
array is indexed by const evaluated expressions
Do not warn when constant sized array is indexed by expressions that evaluate to a const value. For instance,
sizeof(T) expression value can be evaluated at compile time and if an array is indexed by such an expression,
it's bounds can be validated.
(rdar://140320289)
---
clang/lib/Analysis/UnsafeBufferUsage.cpp | 7 ++--
.../warn-unsafe-buffer-usage-array.cpp | 32 +++++++++++++++++++
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index a9aff39df64746..bef5fa8624ce48 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -453,8 +453,11 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
return false;
}
- if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
- const APInt ArrIdx = IdxLit->getValue();
+ Expr::EvalResult EVResult;
+ if (Node.getIdx()->EvaluateAsInt(EVResult, Finder->getASTContext())) {
+ llvm::APSInt ArrIdx = EVResult.Val.getInt();
+ // FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
+ // bug
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
return true;
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index 7dd6c83dbba2a8..e80b54b7c69677 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -92,3 +92,35 @@ char access_strings() {
c = array_string[5];
return c;
}
+
+struct T {
+ int array[10];
+};
+
+const int index = 1;
+
+constexpr int get_const(int x) {
+ if(x < 3)
+ return ++x;
+ else
+ return x + 5;
+};
+
+void array_indexed_const_expr(unsigned idx) {
+ // expected-note at +2 {{change type of 'arr' to 'std::array' to label it for hardening}}
+ // expected-warning at +1{{'arr' is an unsafe buffer that does not perform bounds checks}}
+ int arr[10];
+ arr[sizeof(int)] = 5;
+
+ int array[sizeof(T)];
+ array[sizeof(int)] = 5;
+ array[sizeof(T) -1 ] = 3;
+
+ int k = arr[6 & 5];
+ k = arr[2 << index];
+ k = arr[8 << index]; // expected-note {{used in buffer access here}}
+ k = arr[16 >> 1];
+ k = arr[get_const(index)];
+ k = arr[get_const(5)]; // expected-note {{used in buffer access here}}
+ k = arr[get_const(4)];
+}
More information about the cfe-commits
mailing list