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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits