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 | d239387098ff0ce0d13735e8f3df69e4efe46cea (patch) | |
| tree | 8b3cf96e6c80aace376c6c29618f794105c24eee | |
| parent | 585583c8dd13bebe6fe5851ba3b872cfea411cdf (diff) | |
| download | bcm5719-llvm-d239387098ff0ce0d13735e8f3df69e4efe46cea.tar.gz bcm5719-llvm-d239387098ff0ce0d13735e8f3df69e4efe46cea.zip | |
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.
llvm-svn: 154646
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 24 | ||||
| -rw-r--r-- | clang/test/SemaCXX/goto.cpp | 10 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc-jump-block.m | 13 |
3 files changed, 37 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2333e32e85f..0d0f2f5b99a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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); diff --git a/clang/test/SemaCXX/goto.cpp b/clang/test/SemaCXX/goto.cpp index e55e8807239..24bcb7c5167 100644 --- a/clang/test/SemaCXX/goto.cpp +++ b/clang/test/SemaCXX/goto.cpp @@ -115,3 +115,13 @@ namespace PR10620 { ; } } + +namespace test12 { + struct A { A(); A(const A&); ~A(); }; + void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location + goto lbl; // expected-error {{goto into protected scope}} + (void) ^{ (void) a; }; + lbl: + return; + } +} diff --git a/clang/test/SemaObjC/arc-jump-block.m b/clang/test/SemaObjC/arc-jump-block.m index fdd2dbff00a..26a1fc839d7 100644 --- a/clang/test/SemaObjC/arc-jump-block.m +++ b/clang/test/SemaObjC/arc-jump-block.m @@ -82,3 +82,16 @@ extern __attribute__((visibility("default"))) struct dispatch_queue_s _dispatch_ - (void)pageLeft {} - (void)pageRight {} @end + +// Test 2. rdar://problem/11150919 +int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location + switch (state) { + case 0: + (void) ^{ (void) obj; }; + return 0; + + default: // expected-error {{switch case is in protected scope}} + return 1; + } +} + |

