summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/CFG.cpp
diff options
context:
space:
mode:
authorDevin Coughlin <dcoughlin@apple.com>2015-11-25 22:35:37 +0000
committerDevin Coughlin <dcoughlin@apple.com>2015-11-25 22:35:37 +0000
commitb6029b7ef449305ac58845e99306b9faa2d240e7 (patch)
tree67e08d10c5972645ec054be7a514e7bb61696359 /clang/lib/Analysis/CFG.cpp
parenta774d719a0f9362df894ce8a4090aba79925a1ae (diff)
downloadbcm5719-llvm-b6029b7ef449305ac58845e99306b9faa2d240e7.tar.gz
bcm5719-llvm-b6029b7ef449305ac58845e99306b9faa2d240e7.zip
[analyzer] Include block capture copy expressions in the CFG.
This prevents spurious dead store warnings when a C++ lambda is casted to a block. I've also added several tests documenting our still-incomplete support for lambda-to-block casts. rdar://problem/22236293 llvm-svn: 254107
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r--clang/lib/Analysis/CFG.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index fba9a41f232..cff15cb3fd8 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -460,6 +460,7 @@ private:
CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc);
CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I);
CFGBlock *VisitLabelStmt(LabelStmt *L);
+ CFGBlock *VisitBlockExpr(BlockExpr *E, AddStmtChoice asc);
CFGBlock *VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc);
CFGBlock *VisitLogicalOperator(BinaryOperator *B);
std::pair<CFGBlock *, CFGBlock *> VisitLogicalOperator(BinaryOperator *B,
@@ -1453,7 +1454,7 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
case Stmt::BlockExprClass:
- return VisitNoRecurse(cast<Expr>(S), asc);
+ return VisitBlockExpr(cast<BlockExpr>(S), asc);
case Stmt::BreakStmtClass:
return VisitBreakStmt(cast<BreakStmt>(S));
@@ -2333,6 +2334,18 @@ CFGBlock *CFGBuilder::VisitLabelStmt(LabelStmt *L) {
return LabelBlock;
}
+CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
+ CFGBlock *LastBlock = VisitNoRecurse(E, asc);
+ for (const BlockDecl::Capture &CI : E->getBlockDecl()->captures()) {
+ if (Expr *CopyExpr = CI.getCopyExpr()) {
+ CFGBlock *Tmp = Visit(CopyExpr);
+ if (Tmp)
+ LastBlock = Tmp;
+ }
+ }
+ return LastBlock;
+}
+
CFGBlock *CFGBuilder::VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc) {
CFGBlock *LastBlock = VisitNoRecurse(E, asc);
for (LambdaExpr::capture_init_iterator it = E->capture_init_begin(),
OpenPOWER on IntegriCloud