[PATCH] D63538: [CFG] Add a new function to get the proper condition of a CFGBlock
Kristóf Umann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 3 10:32:06 PDT 2019
Szelethus updated this revision to Diff 207833.
Szelethus retitled this revision from "[analyzer][CFG] Return the correct terminator condition" to "[CFG] Add a new function to get the proper condition of a CFGBlock".
Szelethus edited the summary of this revision.
Szelethus added a comment.
Let's not try to tinker with something in a way that could have unforeseen consequences. I added a new method to simply get the condition the way I (and probably @xazax.hun) will need it.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D63538/new/
https://reviews.llvm.org/D63538
Files:
clang/include/clang/Analysis/CFG.h
clang/lib/Analysis/CFG.cpp
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -5615,6 +5615,22 @@
Out << JsonFormat(TempOut.str(), AddQuotes);
}
+const Expr *CFGBlock::getLastCondition() 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;
+
+ // This should be the condition of the terminator block.
+ const Stmt *S = rbegin()->castAs<CFGStmt>().getStmt();
+ if (isa<ObjCForCollectionStmt>(S))
+ return nullptr;
+
+ // Only ObjCForCollectionStmt is known not to be a non-Expr terminator.
+ const Expr *Cond = cast<Expr>(S);
+ return Cond->IgnoreParens();
+}
+
Stmt *CFGBlock::getTerminatorCondition(bool StripParens) {
Stmt *Terminator = getTerminatorStmt();
if (!Terminator)
Index: clang/include/clang/Analysis/CFG.h
===================================================================
--- clang/include/clang/Analysis/CFG.h
+++ clang/include/clang/Analysis/CFG.h
@@ -860,6 +860,14 @@
Stmt *getTerminatorStmt() { return Terminator.getStmt(); }
const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); }
+ /// \returns the last (\c rbegin()) condition, e.g. observe the following code
+ /// snippet:
+ /// if (A && B && C)
+ /// A block would be created for \c A, \c B, and \c C. For the latter,
+ /// \c getTerminatorStmt() would retrieve the entire condition, rather than
+ /// C itself, while this method would only return C.
+ const Expr *getLastCondition() const;
+
Stmt *getTerminatorCondition(bool StripParens = true);
const Stmt *getTerminatorCondition(bool StripParens = true) const {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63538.207833.patch
Type: text/x-patch
Size: 1803 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190703/a731e730/attachment.bin>
More information about the cfe-commits
mailing list