Szelethus created this revision. Szelethus added reviewers: NoQ, xazax.hun, a_sidorin, baloghadamsoftware, rnkovacs, dcoughlin. Szelethus added a project: clang. Herald added subscribers: cfe-commits, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, szepet, whisperity.
For the following terminator statement: if (A && B && C && D) The built CFG is the following: [B5 (ENTRY)] Succs (1): B4 [B1] 1: 10 2: j 3: [B1.2] (ImplicitCastExpr, LValueToRValue, int) 4: [B1.1] / [B1.3] 5: int x = 10 / j; Preds (1): B2 Succs (1): B0 [B2] 1: C 2: [B2.1] (ImplicitCastExpr, LValueToRValue, _Bool) T: if [B4.4] && [B3.2] && [B2.2] Preds (1): B3 Succs (2): B1 B0 [B3] 1: B 2: [B3.1] (ImplicitCastExpr, LValueToRValue, _Bool) T: [B4.4] && [B3.2] && ... Preds (1): B4 Succs (2): B2 B0 [B4] 1: 0 2: int j = 0; 3: A 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) T: [B4.4] && ... Preds (1): B5 Succs (2): B3 B0 [B0 (EXIT)] Preds (4): B1 B2 B3 B4 However, even though the path of execution in B2 <https://reviews.llvm.org/B2> only depends on C's value, `CFGBlock::getCondition()` would return the entire condition (`A && B && C`). For B3 <https://reviews.llvm.org/B3>, it would return `A && B`. I changed this the actual condition. The tests show an addition of an extra arrow for `ObjCForCollectionStmt`, all of them similar to this: F9306419: image.png <https://reviews.llvm.org/F9306419> (the first arrow the addition) Repository: rC Clang https://reviews.llvm.org/D63538 Files: clang/include/clang/Analysis/CFG.h clang/lib/Analysis/CFG.cpp clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist clang/test/Analysis/Inputs/expected-plists/plist-output.m.plist
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 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>160</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>160</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>160</integer> + <key>col</key><integer>18</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>160</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>160</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -5755,12 +5789,12 @@ <array> <dict> <key>line</key><integer>160</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>160</integer> - <key>col</key><integer>13</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -5780,12 +5814,12 @@ <array> <dict> <key>line</key><integer>160</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>160</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> 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 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>131</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>131</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>131</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>131</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>131</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>15</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -2194,12 +2228,12 @@ <array> <dict> <key>line</key><integer>131</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>15</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>131</integer> - <key>col</key><integer>10</integer> + <key>col</key><integer>15</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -2219,12 +2253,12 @@ <array> <dict> <key>line</key><integer>131</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>15</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>131</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>15</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -2457,11 +2491,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>137</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>137</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>137</integer> + <key>col</key><integer>18</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>137</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>137</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -2469,12 +2537,12 @@ <array> <dict> <key>line</key><integer>137</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>137</integer> - <key>col</key><integer>13</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -2494,12 +2562,12 @@ <array> <dict> <key>line</key><integer>137</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>18</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>137</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -13397,11 +13465,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>16</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -13409,12 +13511,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>11</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -13434,12 +13536,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -14021,11 +14123,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>16</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -14033,12 +14169,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>11</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -14058,12 +14194,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -15564,11 +15700,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>16</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -15576,12 +15746,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>11</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -15601,12 +15771,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -17234,11 +17404,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>16</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -17246,12 +17450,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>11</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -17271,12 +17475,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -19129,11 +19333,45 @@ </array> </dict> <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>16</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>467</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> <key>kind</key><string>event</string> <key>location</key> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <key>ranges</key> @@ -19141,12 +19379,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>8</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>11</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> @@ -19166,12 +19404,12 @@ <array> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>3</integer> + <key>col</key><integer>16</integer> <key>file</key><integer>0</integer> </dict> <dict> <key>line</key><integer>467</integer> - <key>col</key><integer>5</integer> + <key>col</key><integer>20</integer> <key>file</key><integer>0</integer> </dict> </array> 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<CFGStmt>().getStmt(); + assert(S); - 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; + const Expr *Cond; - case Stmt::ConditionalOperatorClass: - E = cast<ConditionalOperator>(Terminator)->getCond(); - break; + if (!(Cond = dyn_cast<Expr>(S))) { + // Only ObjCForCollectionStmt is known not to be a non-Expr terminator. + const auto *O = cast<ObjCForCollectionStmt>(S); - case Stmt::BinaryOperatorClass: // '&&' and '||' - E = cast<BinaryOperator>(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/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<CFGBlock*>(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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits