[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