Index: clang/include/clang/Analysis/CFG.h =================================================================== --- clang/include/clang/Analysis/CFG.h +++ clang/include/clang/Analysis/CFG.h @@ -860,11 +860,9 @@ Stmt *getTerminatorStmt() { return Terminator.getStmt(); } const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } - Stmt *getTerminatorCondition(bool StripParens = true); - - const Stmt *getTerminatorCondition(bool StripParens = true) const { - return const_cast(this)->getTerminatorCondition(StripParens); - } + /// \returns the condition of the terminator (condition of an if statement, + /// for loop, etc). + const Expr *getTerminatorCondition(bool StripParens = true) const; const Stmt *getLoopTarget() const { return LoopTarget; } Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -5615,69 +5615,27 @@ Out << JsonFormat(TempOut.str(), AddQuotes); } -Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { - Stmt *Terminator = getTerminatorStmt(); - if (!Terminator) +const Expr *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; + // This should be the condition of the terminator block. + const Stmt *S = rbegin()->castAs().getStmt(); + assert(S); - 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; + const Expr *Cond; - case Stmt::ConditionalOperatorClass: - E = cast(Terminator)->getCond(); - break; + if (!(Cond = dyn_cast(S))) { + // Only ObjCForCollectionStmt is known not to be a non-Expr terminator. + const auto *O = cast(S); - case Stmt::BinaryOperatorClass: // '&&' and '||' - E = cast(Terminator)->getLHS(); - break; - - case Stmt::ObjCForCollectionStmtClass: - return Terminator; + Cond = O->getCollection(); } - if (!StripParens) - return E; - - return E ? E->IgnoreParens() : nullptr; + assert(Cond); + return StripParens ? Cond->IgnoreParens() : Cond; } //===----------------------------------------------------------------------===// Index: clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist +++ clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist @@ -2182,11 +2182,45 @@ + kindcontrol + edges + + + start + + + line131 + col3 + file0 + + + line131 + col5 + file0 + + + end + + + line131 + col15 + file0 + + + line131 + col15 + file0 + + + + + + kindevent location line131 - col8 + col15 file0 ranges @@ -2194,12 +2228,12 @@ line131 - col8 + col15 file0 line131 - col10 + col15 file0 @@ -2219,12 +2253,12 @@ line131 - col3 + col15 file0 line131 - col5 + col15 file0 @@ -2457,11 +2491,45 @@ + kindcontrol + edges + + + start + + + line137 + col3 + file0 + + + line137 + col5 + file0 + + + end + + + line137 + col18 + file0 + + + line137 + col20 + file0 + + + + + + kindevent location line137 - col8 + col18 file0 ranges @@ -2469,12 +2537,12 @@ line137 - col8 + col18 file0 line137 - col13 + col20 file0 @@ -2494,12 +2562,12 @@ line137 - col3 + col18 file0 line137 - col5 + col20 file0 @@ -13397,11 +13465,45 @@ + kindcontrol + edges + + + start + + + line467 + col3 + file0 + + + line467 + col5 + file0 + + + end + + + line467 + col16 + file0 + + + line467 + col20 + file0 + + + + + + kindevent location line467 - col8 + col16 file0 ranges @@ -13409,12 +13511,12 @@ line467 - col8 + col16 file0 line467 - col11 + col20 file0 @@ -13434,12 +13536,12 @@ line467 - col3 + col16 file0 line467 - col5 + col20 file0 @@ -14021,11 +14123,45 @@ + kindcontrol + edges + + + start + + + line467 + col3 + file0 + + + line467 + col5 + file0 + + + end + + + line467 + col16 + file0 + + + line467 + col20 + file0 + + + + + + kindevent location line467 - col8 + col16 file0 ranges @@ -14033,12 +14169,12 @@ line467 - col8 + col16 file0 line467 - col11 + col20 file0 @@ -14058,12 +14194,12 @@ line467 - col3 + col16 file0 line467 - col5 + col20 file0 @@ -15564,11 +15700,45 @@ + kindcontrol + edges + + + start + + + line467 + col3 + file0 + + + line467 + col5 + file0 + + + end + + + line467 + col16 + file0 + + + line467 + col20 + file0 + + + + + + kindevent location line467 - col8 + col16 file0 ranges @@ -15576,12 +15746,12 @@ line467 - col8 + col16 file0 line467 - col11 + col20 file0 @@ -15601,12 +15771,12 @@ line467 - col3 + col16 file0 line467 - col5 + col20 file0 @@ -17234,11 +17404,45 @@ + kindcontrol + edges + + + start + + + line467 + col3 + file0 + + + line467 + col5 + file0 + + + end + + + line467 + col16 + file0 + + + line467 + col20 + file0 + + + + + + kindevent location line467 - col8 + col16 file0 ranges @@ -17246,12 +17450,12 @@ line467 - col8 + col16 file0 line467 - col11 + col20 file0 @@ -17271,12 +17475,12 @@ line467 - col3 + col16 file0 line467 - col5 + col20 file0 @@ -19129,11 +19333,45 @@ + kindcontrol + edges + + + start + + + line467 + col3 + file0 + + + line467 + col5 + file0 + + + end + + + line467 + col16 + file0 + + + line467 + col20 + file0 + + + + + + kindevent location line467 - col8 + col16 file0 ranges @@ -19141,12 +19379,12 @@ line467 - col8 + col16 file0 line467 - col11 + col20 file0 @@ -19166,12 +19404,12 @@ line467 - col3 + col16 file0 line467 - col5 + col20 file0 Index: clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist +++ clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist @@ -5743,11 +5743,45 @@ + kindcontrol + edges + + + start + + + line160 + col3 + file0 + + + line160 + col5 + file0 + + + end + + + line160 + col18 + file0 + + + line160 + col20 + file0 + + + + + + kindevent location line160 - col8 + col18 file0 ranges @@ -5755,12 +5789,12 @@ line160 - col8 + col18 file0 line160 - col13 + col20 file0 @@ -5780,12 +5814,12 @@ line160 - col3 + col18 file0 line160 - col5 + col20 file0