aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/CFG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r--clang/lib/Analysis/CFG.cpp51
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