aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorMalavika Samak <malavika.samak@gmail.com>2025-05-16 18:33:51 -0700
committerGitHub <noreply@github.com>2025-05-16 18:33:51 -0700
commit39315663a40a261772df94218fd33e205e888e54 (patch)
tree7bd3e66ecfe68f29ad985701a16729b5f3bd5520 /clang/lib/Analysis
parentf7ef8dcbad9d5ac6cf2a8917d5ce03564fdfd0d8 (diff)
downloadllvm-39315663a40a261772df94218fd33e205e888e54.zip
llvm-39315663a40a261772df94218fd33e205e888e54.tar.gz
llvm-39315663a40a261772df94218fd33e205e888e54.tar.bz2
[-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@apple.com>
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/UnsafeBufferUsage.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 5b72382..ec648e1 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() &&