diff options
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index a533a8d97b84..4c1ea8995f9f 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -542,6 +542,7 @@ public: private: // Visitors to walk an AST and construct the CFG. + CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc); CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc); CFGBlock *VisitBreakStmt(BreakStmt *B); @@ -1428,7 +1429,7 @@ void CFGBuilder::findConstructionContexts( if (Layer->getItem().getKind() == ConstructionContextItem::ElidableConstructorKind) { auto *MTE = cast<MaterializeTemporaryExpr>(Child); - findConstructionContexts(withExtraLayer(MTE), MTE->GetTemporaryExpr()); + findConstructionContexts(withExtraLayer(MTE), MTE->getSubExpr()); } break; } @@ -1694,7 +1695,7 @@ static QualType getReferenceInitTemporaryType(const Expr *Init, // Skip through the temporary-materialization expression. if (const MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) { - Init = MTE->GetTemporaryExpr(); + Init = MTE->getSubExpr(); if (FoundMTE) *FoundMTE = true; continue; @@ -2135,6 +2136,14 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, default: return VisitStmt(S, asc); + case Stmt::ImplicitValueInitExprClass: + if (BuildOpts.OmitImplicitValueInitializers) + return Block; + return VisitStmt(S, asc); + + case Stmt::InitListExprClass: + return VisitInitListExpr(cast<InitListExpr>(S), asc); + case Stmt::AddrLabelExprClass: return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc); @@ -2341,15 +2350,37 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) { // Visit the children in their reverse order so that they appear in // left-to-right (natural) order in the CFG. reverse_children RChildren(S); - for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end(); - I != E; ++I) { - if (Stmt *Child = *I) + for (Stmt *Child : RChildren) { + if (Child) if (CFGBlock *R = Visit(Child)) B = R; } return B; } +CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) { + if (asc.alwaysAdd(*this, ILE)) { + autoCreateBlock(); + appendStmt(Block, ILE); + } + CFGBlock *B = Block; + + reverse_children RChildren(ILE); + for (Stmt *Child : RChildren) { + if (!Child) + continue; + if (CFGBlock *R = Visit(Child)) + B = R; + if (BuildOpts.AddCXXDefaultInitExprInAggregates) { + if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Child)) + if (Stmt *Child = DIE->getExpr()) + if (CFGBlock *R = Visit(Child)) + B = R; + } + } + return B; +} + CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc) { AddressTakenLabels.insert(A->getLabel()); @@ -3462,7 +3493,7 @@ CFGBuilder::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE, AddStmtChoice asc) { findConstructionContexts( ConstructionContextLayer::create(cfg->getBumpVectorContext(), MTE), - MTE->getTemporary()); + MTE->getSubExpr()); return VisitStmt(MTE, asc); } @@ -4649,7 +4680,7 @@ tryAgain: // Find the expression whose lifetime needs to be extended. E = const_cast<Expr *>( cast<MaterializeTemporaryExpr>(E) - ->GetTemporaryExpr() + ->getSubExpr() ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); // Visit the skipped comma operator left-hand sides for other temporaries. for (const Expr *CommaLHS : CommaLHSs) { @@ -5879,12 +5910,16 @@ const Expr *CFGBlock::getLastCondition() const { if (succ_size() < 2) return nullptr; + // FIXME: Is there a better condition expression we can return in this case? + if (size() == 0) + return nullptr; + auto StmtElem = rbegin()->getAs<CFGStmt>(); if (!StmtElem) return nullptr; const Stmt *Cond = StmtElem->getStmt(); - if (isa<ObjCForCollectionStmt>(Cond)) + if (isa<ObjCForCollectionStmt>(Cond) || isa<DeclStmt>(Cond)) return nullptr; // Only ObjCForCollectionStmt is known not to be a non-Expr terminator, hence |