diff options
author | John McCall <rjmccall@apple.com> | 2012-04-13 01:08:17 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-04-13 01:08:17 +0000 |
commit | 97b57a2170c2138fb71d336d77c6db7728938108 (patch) | |
tree | 0de78e132b2ac12549766cb55c1161c54fc55931 /lib | |
parent | 9d4e87e52c1424bad660f7621fb0cf6d6aaad666 (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.cpp | 24 |
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); |