diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/JumpDiagnostics.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | clang/test/Sema/block-misc.c | 13 |
4 files changed, 19 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9b9f96e5dc9..7fc237bf0b1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1066,6 +1066,8 @@ def note_protected_by_cxx_try : Note< "jump bypasses initialization of try block">; def note_protected_by_cxx_catch : Note< "jump bypasses initialization of catch block">; +def note_protected_by___block : Note< + "jump bypasses setup of __block variable">; def err_func_returning_array_function : Error< "function cannot return array or function type %0">; diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index ae863f2df1e..853adaa3368 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -83,6 +83,8 @@ static unsigned GetDiagForGotoScopeDecl(const Decl *D) { return diag::note_protected_by_vla; if (VD->hasAttr<CleanupAttr>()) return diag::note_protected_by_cleanup; + if (VD->hasAttr<BlocksAttr>()) + return diag::note_protected_by___block; } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { if (TD->getUnderlyingType()->isVariablyModifiedType()) return diag::note_protected_by_vla_typedef; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index bc497aa1421..28ac9d1982a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1954,7 +1954,8 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl, Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local); bool isVM = T->isVariablyModifiedType(); - if (isVM || NewVD->hasAttr<CleanupAttr>()) + if (isVM || NewVD->hasAttr<CleanupAttr>() || + NewVD->hasAttr<BlocksAttr>()) CurFunctionNeedsScopeChecking = true; if ((isVM && NewVD->hasLinkage()) || diff --git a/clang/test/Sema/block-misc.c b/clang/test/Sema/block-misc.c index 294c295c5f8..1f1cad44a94 100644 --- a/clang/test/Sema/block-misc.c +++ b/clang/test/Sema/block-misc.c @@ -185,3 +185,16 @@ void test18() { void (^const blockA)(void) = ^{ }; blockA = ^{ }; // expected-error {{read-only variable is not assignable}} } + +// rdar://7072507 +int test19() { + goto L0; // expected-error {{illegal goto into protected scope}} + + __block int x; // expected-note {{jump bypasses setup of __block variable}} +L0: + x = 0; + ^(){ ++x; }(); + return x; +} + + |