From: Kristof Umann Date: Wed, 3 Jul 2019 13:03:33 +0000 (+0000) Subject: Revert "[analyzer][CFG] Return the correct terminator condition" X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd7160bc45759a8df33f25d5eb6029e6acde9c2f;p=clang Revert "[analyzer][CFG] Return the correct terminator condition" This reverts commit 7a57118a6fcfa3770f984453543bbdfd0b233e84. Causes a bunch of crashes, I need to time to evaluate this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365037 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 945d36498c..d8b3d6ff71 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -860,12 +860,10 @@ public: Stmt *getTerminatorStmt() { return Terminator.getStmt(); } const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } - /// \returns the condition of the terminator (condition of an if statement, - /// for loop, etc). - const Stmt *getTerminatorCondition(bool StripParens = true) const; + Stmt *getTerminatorCondition(bool StripParens = true); - const Expr *getTerminatorConditionExpr(bool StripParens = true) const { - return dyn_cast_or_null(getTerminatorCondition(StripParens)); + const Stmt *getTerminatorCondition(bool StripParens = true) const { + return const_cast(this)->getTerminatorCondition(StripParens); } const Stmt *getLoopTarget() const { return LoopTarget; } diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 3e6185c76c..b53bfcca37 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -5615,21 +5615,69 @@ void CFGBlock::printTerminatorJson(raw_ostream &Out, const LangOptions &LO, Out << JsonFormat(TempOut.str(), AddQuotes); } -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) +Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { + Stmt *Terminator = getTerminatorStmt(); + if (!Terminator) return nullptr; - // This should be the condition of the terminator block. - const Stmt *S = rbegin()->castAs().getStmt(); - if (isa(S)) { - return getTerminatorStmt(); + Expr *E = nullptr; + + switch (Terminator->getStmtClass()) { + default: + break; + + case Stmt::CXXForRangeStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::ForStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::WhileStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::DoStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::IfStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::ChooseExprClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::IndirectGotoStmtClass: + E = cast(Terminator)->getTarget(); + break; + + case Stmt::SwitchStmtClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::BinaryConditionalOperatorClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::ConditionalOperatorClass: + E = cast(Terminator)->getCond(); + break; + + case Stmt::BinaryOperatorClass: // '&&' and '||' + E = cast(Terminator)->getLHS(); + break; + + case Stmt::ObjCForCollectionStmtClass: + return Terminator; } - // Only ObjCForCollectionStmt is known not to be a non-Expr terminator. - const Expr *Cond = cast(S); - return StripParens ? Cond->IgnoreParens() : Cond; + if (!StripParens) + return E; + + return E ? E->IgnoreParens() : nullptr; } //===----------------------------------------------------------------------===//