diff options
author | Malavika Samak <malavika.samak@gmail.com> | 2025-05-16 18:33:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-16 18:33:51 -0700 |
commit | 39315663a40a261772df94218fd33e205e888e54 (patch) | |
tree | 7bd3e66ecfe68f29ad985701a16729b5f3bd5520 /clang/lib/Analysis | |
parent | f7ef8dcbad9d5ac6cf2a8917d5ce03564fdfd0d8 (diff) | |
download | llvm-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.cpp | 17 |
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() && |