================ @@ -420,25 +420,63 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { // already duplicated // - call both from Sema and from here - const auto *BaseDRE = - dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts()); - if (!BaseDRE) + if (const auto *BaseDRE = + dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts())) { + if (!BaseDRE->getDecl()) + return false; + if (const auto *CATy = Finder->getASTContext().getAsConstantArrayType( + BaseDRE->getDecl()->getType())) { + 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() < CATy->getLimitedSize()) + return true; + } + } + } + + if (const auto *BaseSL = + dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts())) { + if (const auto *CATy = + Finder->getASTContext().getAsConstantArrayType(BaseSL->getType())) { + 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() < CATy->getLimitedSize()) + return true; + } + } + } + + return false; +} + +AST_MATCHER(BinaryOperator, isSafePtrArithmetic) { + if (Node.getOpcode() != BinaryOperatorKind::BO_Add) return false; - if (!BaseDRE->getDecl()) + + const auto *LHSDRE = dyn_cast<DeclRefExpr>(Node.getLHS()->IgnoreImpCasts()); + if (!LHSDRE) return false; + const auto *CATy = Finder->getASTContext().getAsConstantArrayType( - BaseDRE->getDecl()->getType()); + LHSDRE->getDecl()->getType()); if (!CATy) return false; - 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() < CATy->getLimitedSize()) - return true; - } + const auto *RHSIntLit = dyn_cast<IntegerLiteral>(Node.getRHS()); + if (!RHSIntLit) + return false; + + const APInt BufferOffset = RHSIntLit->getValue(); + + if (BufferOffset.isNonNegative() && ---------------- pkasting wrote:
That seems reasonable, but if that's the route, I might want to file a bug pre-emptively on further cases that should, or should not, be considered for future work. One of my thoughts with the refactor suggestion below was that if the arithmetic/detection got more complex, it would be easier to implement consistently in a single place. https://github.com/llvm/llvm-project/pull/92432 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits