diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-03-01 18:41:00 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-03-01 18:41:00 +0000 |
commit | 3aea4dac830cb03d883a13ab30c28a3a53beca58 (patch) | |
tree | 9bf4f73c8a61de06421787a085df0243de518685 /lib/Sema/SemaChecking.cpp | |
parent | 9e876876afc13aa671cc11a17c19907c599b9ab9 (diff) |
For C++, enhance -Warray-bounds to recursively analyze array subscript accesses in ?: expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126766 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d83809d708..cdcab31eef 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -3134,10 +3134,11 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) { << TRange << Op->getSourceRange(); } -void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) { +static void CheckArrayAccess_Check(Sema &S, + const clang::ArraySubscriptExpr *E) { const Expr *BaseExpr = E->getBase()->IgnoreParenImpCasts(); const ConstantArrayType *ArrayTy = - Context.getAsConstantArrayType(BaseExpr->getType()); + S.Context.getAsConstantArrayType(BaseExpr->getType()); if (!ArrayTy) return; @@ -3145,7 +3146,7 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) { if (IndexExpr->isValueDependent()) return; llvm::APSInt index; - if (!IndexExpr->isIntegerConstantExpr(index, Context)) + if (!IndexExpr->isIntegerConstantExpr(index, S.Context)) return; if (index.isUnsigned() || !index.isNegative()) { @@ -3160,15 +3161,16 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) { if (index.slt(size)) return; - DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr, - PDiag(diag::warn_array_index_exceeds_bounds) - << index.toString(10, true) << size.toString(10, true) - << IndexExpr->getSourceRange()); + S.DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr, + S.PDiag(diag::warn_array_index_exceeds_bounds) + << index.toString(10, true) + << size.toString(10, true) + << IndexExpr->getSourceRange()); } else { - DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr, - PDiag(diag::warn_array_index_precedes_bounds) - << index.toString(10, true) - << IndexExpr->getSourceRange()); + S.DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr, + S.PDiag(diag::warn_array_index_precedes_bounds) + << index.toString(10, true) + << IndexExpr->getSourceRange()); } const NamedDecl *ND = NULL; @@ -3177,8 +3179,29 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) { if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr)) ND = dyn_cast<NamedDecl>(ME->getMemberDecl()); if (ND) - DiagRuntimeBehavior(ND->getLocStart(), BaseExpr, - PDiag(diag::note_array_index_out_of_bounds) - << ND->getDeclName()); + S.DiagRuntimeBehavior(ND->getLocStart(), BaseExpr, + S.PDiag(diag::note_array_index_out_of_bounds) + << ND->getDeclName()); +} + +void Sema::CheckArrayAccess(const Expr *expr) { + while (true) + switch (expr->getStmtClass()) { + case Stmt::ParenExprClass: + expr = cast<ParenExpr>(expr)->getSubExpr(); + continue; + case Stmt::ArraySubscriptExprClass: + CheckArrayAccess_Check(*this, cast<ArraySubscriptExpr>(expr)); + return; + case Stmt::ConditionalOperatorClass: { + const ConditionalOperator *cond = cast<ConditionalOperator>(expr); + if (const Expr *lhs = cond->getLHS()) + CheckArrayAccess(lhs); + if (const Expr *rhs = cond->getRHS()) + CheckArrayAccess(rhs); + return; + } + default: + return; + } } - |