[clang] [-Wunsafe-buffer-usage] Suppress warning for multi-dimensional constant arrays (PR #118249)
Malavika Samak via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 5 21:48:01 PST 2024
================
@@ -433,37 +433,36 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
// already duplicated
// - call both from Sema and from here
- const auto *BaseDRE =
- dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts());
- const auto *SLiteral =
- dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts());
- uint64_t size;
-
- if (!BaseDRE && !SLiteral)
- return false;
-
- if (BaseDRE) {
- if (!BaseDRE->getDecl())
- return false;
- const auto *CATy = Finder->getASTContext().getAsConstantArrayType(
- BaseDRE->getDecl()->getType());
- if (!CATy) {
+ std::function<bool(const ArraySubscriptExpr *)> CheckBounds =
+ [&CheckBounds](const ArraySubscriptExpr *ASE) -> bool {
+ uint64_t limit;
+ if (const auto *CATy =
+ dyn_cast<ConstantArrayType>(ASE->getBase()
+ ->IgnoreParenImpCasts()
+ ->getType()
+ ->getUnqualifiedDesugaredType())) {
+ limit = CATy->getLimitedSize();
+ } else if (const auto *SLiteral = dyn_cast<StringLiteral>(
+ ASE->getBase()->IgnoreParenImpCasts())) {
+ limit = SLiteral->getLength() + 1;
+ } else {
return false;
}
- size = CATy->getLimitedSize();
- } else if (SLiteral) {
- size = SLiteral->getLength() + 1;
- }
- if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
- const APInt ArrIdx = IdxLit->getValue();
- // FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
- // bug
- if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size)
+ if (const auto *IdxLit = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
+ const APInt ArrIdx = IdxLit->getValue();
+ if (!ArrIdx.isNonNegative() || ArrIdx.getLimitedValue() >= limit)
+ return false;
+ if (const auto *BaseASE = dyn_cast<ArraySubscriptExpr>(
+ ASE->getBase()->IgnoreParenImpCasts())) {
+ return CheckBounds(BaseASE);
----------------
malavikasamak wrote:
That is how it is supposed to work. However, we will have cases where array dimensions go upto 3 and higher than 3 dimensions should be quite rare indeed. For each dimension we do the following: retrieve the size of the type and compare it against the index used by the operation. This to me presents as a natural fit for a recursive solution, both in terms of code reuse and readability. That said, I am open to other solutions.
https://github.com/llvm/llvm-project/pull/118249
More information about the cfe-commits
mailing list