diff options
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 111 |
1 files changed, 56 insertions, 55 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2d3d36f..17dd5c9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14387,62 +14387,63 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, PDiag(diag::note_array_declared_here) << ND); } -void Sema::CheckArrayAccess(const Expr *expr) { - int AllowOnePastEnd = 0; - while (expr) { - expr = expr->IgnoreParenImpCasts(); - switch (expr->getStmtClass()) { - case Stmt::ArraySubscriptExprClass: { - const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr); - CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE, - AllowOnePastEnd > 0); - expr = ASE->getBase(); - break; - } - case Stmt::MemberExprClass: { - expr = cast<MemberExpr>(expr)->getBase(); - break; - } - case Stmt::OMPArraySectionExprClass: { - const OMPArraySectionExpr *ASE = cast<OMPArraySectionExpr>(expr); - if (ASE->getLowerBound()) - CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(), - /*ASE=*/nullptr, AllowOnePastEnd > 0); - return; - } - case Stmt::UnaryOperatorClass: { - // Only unwrap the * and & unary operators - const UnaryOperator *UO = cast<UnaryOperator>(expr); - expr = UO->getSubExpr(); - switch (UO->getOpcode()) { - case UO_AddrOf: - AllowOnePastEnd++; - break; - case UO_Deref: - AllowOnePastEnd--; - break; - default: - return; - } - break; - } - 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; - } - case Stmt::CXXOperatorCallExprClass: { - const auto *OCE = cast<CXXOperatorCallExpr>(expr); - for (const auto *Arg : OCE->arguments()) - CheckArrayAccess(Arg); - return; - } - default: - return; +void Sema::CheckArrayAccess(const Expr *expr, int AllowOnePastEnd) { + if (!expr) + return; + + expr = expr->IgnoreParenCasts(); + switch (expr->getStmtClass()) { + case Stmt::ArraySubscriptExprClass: { + const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr); + CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE, AllowOnePastEnd > 0); + CheckArrayAccess(ASE->getBase(), AllowOnePastEnd); + return; + } + case Stmt::MemberExprClass: { + expr = cast<MemberExpr>(expr)->getBase(); + CheckArrayAccess(expr, /*AllowOnePastEnd=*/0); + return; + } + case Stmt::OMPArraySectionExprClass: { + const OMPArraySectionExpr *ASE = cast<OMPArraySectionExpr>(expr); + if (ASE->getLowerBound()) + CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(), + /*ASE=*/nullptr, AllowOnePastEnd > 0); + return; + } + case Stmt::UnaryOperatorClass: { + // Only unwrap the * and & unary operators + const UnaryOperator *UO = cast<UnaryOperator>(expr); + expr = UO->getSubExpr(); + switch (UO->getOpcode()) { + case UO_AddrOf: + AllowOnePastEnd++; + break; + case UO_Deref: + AllowOnePastEnd--; + break; + default: + return; } + CheckArrayAccess(expr, AllowOnePastEnd); + return; + } + case Stmt::ConditionalOperatorClass: { + const ConditionalOperator *cond = cast<ConditionalOperator>(expr); + if (const Expr *lhs = cond->getLHS()) + CheckArrayAccess(lhs, AllowOnePastEnd); + if (const Expr *rhs = cond->getRHS()) + CheckArrayAccess(rhs, AllowOnePastEnd); + return; + } + case Stmt::CXXOperatorCallExprClass: { + const auto *OCE = cast<CXXOperatorCallExpr>(expr); + for (const auto *Arg : OCE->arguments()) + CheckArrayAccess(Arg); + return; + } + default: + return; } } |