diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2019-07-05 09:52:00 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2019-07-05 09:52:00 +0000 |
commit | d5c9d9b6820f269f105ac278ba26d040630fe901 (patch) | |
tree | daede4e4d2277e433a17ce6bc0e9f5d8a8387e32 /clang/lib/Analysis/CFG.cpp | |
parent | bb7e97d783efae225c97758f2ff186436ac8d86d (diff) | |
download | bcm5719-llvm-d5c9d9b6820f269f105ac278ba26d040630fe901.tar.gz bcm5719-llvm-d5c9d9b6820f269f105ac278ba26d040630fe901.zip |
[CFG] Add a new function to get the proper condition of a CFGBlock
getTerminatorCondition() returned a condition that may be outside of the
block, while the new function returns the proper one:
if (A && B && C) {}
Return C instead of A && B && C.
Differential Revision: https://reviews.llvm.org/D63538
llvm-svn: 365177
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index b53bfcca37c..80f5a46ceab 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -5615,6 +5615,30 @@ void CFGBlock::printTerminatorJson(raw_ostream &Out, const LangOptions &LO, 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 (Terminator.getKind() != CFGTerminator::StmtBranch) + return nullptr; + + // Also, if this method was called on a block that doesn't have 2 successors, + // this block doesn't have retrievable condition. + if (succ_size() < 2) + return nullptr; + + auto StmtElem = rbegin()->getAs<CFGStmt>(); + if (!StmtElem) + return nullptr; + + const Stmt *Cond = StmtElem->getStmt(); + if (isa<ObjCForCollectionStmt>(Cond)) + return nullptr; + + // Only ObjCForCollectionStmt is known not to be a non-Expr terminator, hence + // the cast<>. + return cast<Expr>(Cond)->IgnoreParens(); +} + Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { Stmt *Terminator = getTerminatorStmt(); if (!Terminator) |