diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -1307,6 +1307,12 @@ iterator nodes_begin() { return iterator(Blocks.begin()); } iterator nodes_end() { return iterator(Blocks.end()); } + + llvm::iterator_range nodes() { return {begin(), end()}; } + llvm::iterator_range const_nodes() const { + return {begin(), end()}; + } + const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); } const_iterator nodes_end() const { return const_iterator(Blocks.end()); } @@ -1315,6 +1321,13 @@ const_reverse_iterator rbegin() const { return Blocks.rbegin(); } const_reverse_iterator rend() const { return Blocks.rend(); } + llvm::iterator_range reverse_nodes() { + return {rbegin(), rend()}; + } + llvm::iterator_range const_reverse_nodes() const { + return {rbegin(), rend()}; + } + CFGBlock & getEntry() { return *Entry; } const CFGBlock & getEntry() const { return *Entry; } CFGBlock & getExit() { return *Exit; } diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -325,6 +325,11 @@ } void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { + if (LV.killAtAssign && B->getOpcode() == BO_Assign) { + if (const auto *DR = dyn_cast(B->getLHS()->IgnoreParens())) { + LV.inAssignment[DR] = 1; + } + } if (B->isAssignmentOp()) { if (!LV.killAtAssign) return; @@ -513,29 +518,8 @@ llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs()); // FIXME: we should enqueue using post order. - for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) { - const CFGBlock *block = *it; - worklist.enqueueBlock(block); - - // FIXME: Scan for DeclRefExprs using in the LHS of an assignment. - // We need to do this because we lack context in the reverse analysis - // to determine if a DeclRefExpr appears in such a context, and thus - // doesn't constitute a "use". - if (killAtAssign) - for (CFGBlock::const_iterator bi = block->begin(), be = block->end(); - bi != be; ++bi) { - if (Optional cs = bi->getAs()) { - const Stmt* stmt = cs->getStmt(); - if (const auto *BO = dyn_cast(stmt)) { - if (BO->getOpcode() == BO_Assign) { - if (const auto *DR = - dyn_cast(BO->getLHS()->IgnoreParens())) { - LV->inAssignment[DR] = 1; - } - } - } - } - } + for (const CFGBlock *B : cfg->nodes()) { + worklist.enqueueBlock(B); } while (const CFGBlock *block = worklist.dequeue()) {