summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-04-13 01:08:17 +0000
committerJohn McCall <rjmccall@apple.com>2012-04-13 01:08:17 +0000
commit97b57a2170c2138fb71d336d77c6db7728938108 (patch)
tree0de78e132b2ac12549766cb55c1161c54fc55931 /lib
parent9d4e87e52c1424bad660f7621fb0cf6d6aaad666 (diff)
When we're flagging a protected scope to prevent jumps into the
shadow of a block expression with non-trivial destructed cleanups, we should flag that in the enclosing function, not in the block that we're about to pop. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154646 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaExpr.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2333e32e85..0d0f2f5b99 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9111,15 +9111,6 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
- for (BlockDecl::capture_const_iterator ci = BSI->TheDecl->capture_begin(),
- ce = BSI->TheDecl->capture_end(); ci != ce; ++ci) {
- const VarDecl *variable = ci->getVariable();
- QualType T = variable->getType();
- QualType::DestructionKind destructKind = T.isDestructedType();
- if (destructKind != QualType::DK_none)
- getCurFunction()->setHasBranchProtectedScope();
- }
-
computeNRVO(Body, getCurBlock());
BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
@@ -9127,10 +9118,23 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result);
// If the block isn't obviously global, i.e. it captures anything at
- // all, mark this full-expression as needing a cleanup.
+ // all, then we need to do a few things in the surrounding context:
if (Result->getBlockDecl()->hasCaptures()) {
+ // First, this expression has a new cleanup object.
ExprCleanupObjects.push_back(Result->getBlockDecl());
ExprNeedsCleanups = true;
+
+ // It also gets a branch-protected scope if any of the captured
+ // variables needs destruction.
+ for (BlockDecl::capture_const_iterator
+ ci = Result->getBlockDecl()->capture_begin(),
+ ce = Result->getBlockDecl()->capture_end(); ci != ce; ++ci) {
+ const VarDecl *var = ci->getVariable();
+ if (var->getType().isDestructedType() != QualType::DK_none) {
+ getCurFunction()->setHasBranchProtectedScope();
+ break;
+ }
+ }
}
return Owned(Result);