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 {
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 {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits