[clang] 3931566 - [-Wunsafe-buffer-usage] Fix false warnings when const sized array is safely accessed (array [idx %const]) (#140113)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 16 18:33:54 PDT 2025
Author: Malavika Samak
Date: 2025-05-16T18:33:51-07:00
New Revision: 39315663a40a261772df94218fd33e205e888e54
URL: https://github.com/llvm/llvm-project/commit/39315663a40a261772df94218fd33e205e888e54
DIFF: https://github.com/llvm/llvm-project/commit/39315663a40a261772df94218fd33e205e888e54.diff
LOG: [-Wunsafe-buffer-usage] Fix false warnings when const sized array is safely accessed (array [idx %const]) (#140113)
The -Wunsafe-buffer-usage analysis currently warns when a const sized
array is safely accessed, with an index that is bound by the remainder
operator. The false alarm is now suppressed.
Example:
int circular_buffer(int array[10], uint idx) {
return array[idx %10]; // Safe operation
}
rdar://148443453
---------
Co-authored-by: MalavikaSamak <malavika2 at apple.com>
Added:
Modified:
clang/lib/Analysis/UnsafeBufferUsage.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 5b72382ca9772..ec648e1a17af9 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -600,12 +600,27 @@ static bool isSafeArraySubscript(const ArraySubscriptExpr &Node,
} else if (const auto *BE = dyn_cast<BinaryOperator>(IndexExpr)) {
// For an integer expression `e` and an integer constant `n`, `e & n` and
// `n & e` are bounded by `n`:
- if (BE->getOpcode() != BO_And)
+ if (BE->getOpcode() != BO_And && BE->getOpcode() != BO_Rem)
return false;
const Expr *LHS = BE->getLHS();
const Expr *RHS = BE->getRHS();
+ if (BE->getOpcode() == BO_Rem) {
+ // If n is a negative number, then n % const can be greater than const
+ if (!LHS->getType()->isUnsignedIntegerType()) {
+ return false;
+ }
+
+ if (!RHS->isValueDependent() && RHS->EvaluateAsInt(EVResult, Ctx)) {
+ llvm::APSInt result = EVResult.Val.getInt();
+ if (result.isNonNegative() && result.getLimitedValue() <= limit)
+ return true;
+ }
+
+ return false;
+ }
+
if ((!LHS->isValueDependent() &&
LHS->EvaluateAsInt(EVResult, Ctx)) || // case: `n & e`
(!RHS->isValueDependent() &&
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index 3233999ea8ea2..00daa28b433eb 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -35,7 +35,21 @@ void constant_idx_safe0(unsigned idx) {
buffer[0] = 0;
}
-int array[10]; // expected-warning {{'array' is an unsafe buffer that does not perform bounds checks}}
+int array[10]; // expected-warning 3{{'array' is an unsafe buffer that does not perform bounds checks}}
+
+void circular_access_unsigned(unsigned idx) {
+ array[idx % 10];
+ array[idx % 11]; // expected-note {{used in buffer access here}}
+ array[(idx + 3) % 10];
+ array[(--idx) % 8];
+ array[idx & 9 % 10];
+ array[9 & idx % 11];
+ array [12 % 10];
+}
+
+void circular_access_signed(int idx) {
+ array[idx % 10]; // expected-note {{used in buffer access here}}
+}
void masked_idx1(unsigned long long idx, Foo f) {
// Bitwise and operation
More information about the cfe-commits
mailing list