This revision was automatically updated to reflect the committed changes. Closed by commit rL365036: [analyzer][CFG] Return the correct terminator condition (authored by Szelethus, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D63538?vs=205909&id=207772#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63538/new/ https://reviews.llvm.org/D63538 Files: cfe/trunk/include/clang/Analysis/CFG.h cfe/trunk/lib/Analysis/CFG.cpp
Index: cfe/trunk/lib/Analysis/CFG.cpp =================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -5615,69 +5615,21 @@ Out << JsonFormat(TempOut.str(), AddQuotes); } -Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { - Stmt *Terminator = getTerminatorStmt(); - if (!Terminator) +const Stmt *CFGBlock::getTerminatorCondition(bool StripParens) const { + // If the terminator is a temporary dtor or a virtual base, etc, we can't + // retrieve a meaningful condition, bail out. + if (rbegin()->getKind() != CFGElement::Kind::Statement) return nullptr; - Expr *E = nullptr; - - switch (Terminator->getStmtClass()) { - default: - break; - - case Stmt::CXXForRangeStmtClass: - E = cast<CXXForRangeStmt>(Terminator)->getCond(); - break; - - case Stmt::ForStmtClass: - E = cast<ForStmt>(Terminator)->getCond(); - break; - - case Stmt::WhileStmtClass: - E = cast<WhileStmt>(Terminator)->getCond(); - break; - - case Stmt::DoStmtClass: - E = cast<DoStmt>(Terminator)->getCond(); - break; - - case Stmt::IfStmtClass: - E = cast<IfStmt>(Terminator)->getCond(); - break; - - case Stmt::ChooseExprClass: - E = cast<ChooseExpr>(Terminator)->getCond(); - break; - - case Stmt::IndirectGotoStmtClass: - E = cast<IndirectGotoStmt>(Terminator)->getTarget(); - break; - - case Stmt::SwitchStmtClass: - E = cast<SwitchStmt>(Terminator)->getCond(); - break; - - case Stmt::BinaryConditionalOperatorClass: - E = cast<BinaryConditionalOperator>(Terminator)->getCond(); - break; - - case Stmt::ConditionalOperatorClass: - E = cast<ConditionalOperator>(Terminator)->getCond(); - break; - - case Stmt::BinaryOperatorClass: // '&&' and '||' - E = cast<BinaryOperator>(Terminator)->getLHS(); - break; - - case Stmt::ObjCForCollectionStmtClass: - return Terminator; + // This should be the condition of the terminator block. + const Stmt *S = rbegin()->castAs<CFGStmt>().getStmt(); + if (isa<ObjCForCollectionStmt>(S)) { + return getTerminatorStmt(); } - if (!StripParens) - return E; - - return E ? E->IgnoreParens() : nullptr; + // Only ObjCForCollectionStmt is known not to be a non-Expr terminator. + const Expr *Cond = cast<Expr>(S); + return StripParens ? Cond->IgnoreParens() : Cond; } //===----------------------------------------------------------------------===// Index: cfe/trunk/include/clang/Analysis/CFG.h =================================================================== --- cfe/trunk/include/clang/Analysis/CFG.h +++ cfe/trunk/include/clang/Analysis/CFG.h @@ -860,10 +860,12 @@ Stmt *getTerminatorStmt() { return Terminator.getStmt(); } const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } - Stmt *getTerminatorCondition(bool StripParens = true); + /// \returns the condition of the terminator (condition of an if statement, + /// for loop, etc). + const Stmt *getTerminatorCondition(bool StripParens = true) const; - const Stmt *getTerminatorCondition(bool StripParens = true) const { - return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens); + const Expr *getTerminatorConditionExpr(bool StripParens = true) const { + return dyn_cast_or_null<Expr>(getTerminatorCondition(StripParens)); } const Stmt *getLoopTarget() const { return LoopTarget; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits