summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/JumpDiagnostics.cpp2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp3
-rw-r--r--clang/test/Sema/block-misc.c13
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;
+}
+
+
OpenPOWER on IntegriCloud