]> granicus.if.org Git - clang/commitdiff
Implement goto inside of blocks.
authorMike Stump <mrs@apple.com>
Tue, 19 Jan 2010 23:08:01 +0000 (23:08 +0000)
committerMike Stump <mrs@apple.com>
Tue, 19 Jan 2010 23:08:01 +0000 (23:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93945 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
lib/Sema/SemaStmt.cpp
test/Sema/block-literal.c
test/Sema/block-misc.c
test/Sema/scope-check.c

index 7e59f88fcef5cf20c786ffbb466d76b929a81008..78173be8b5ae82f8ecdf28fe335109dde377452d 100644 (file)
@@ -2458,8 +2458,6 @@ def warn_stringcompare : Warning<
 def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
   " or pick a deployment target that supports them">;
 def err_expected_block_lbrace : Error<"expected '{' in block literal">;
-def err_goto_in_block : Error<
-  "goto not allowed in block literal">;
 def err_return_in_block_expression : Error<
   "return not allowed in block expression literal">;
 def err_block_returns_array : Error<
index 8c740dd1dbf6bfd0e183b0a2ea7111af7ae7a2de..19d38bf9d122d848c4712ced9f152d4340fad2ad 100644 (file)
@@ -6884,6 +6884,26 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
   CurFunctionNeedsScopeChecking = BSI->SavedFunctionNeedsScopeChecking;
 
   BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+
+  bool Good = true;
+  // Check goto/label use.
+  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
+         I = BSI->LabelMap.begin(), E = BSI->LabelMap.end(); I != E; ++I) {
+    LabelStmt *L = I->second;
+
+    // Verify that we have no forward references left.  If so, there was a goto
+    // or address of a label taken, but no definition of it.
+    if (L->getSubStmt() != 0)
+      continue;
+
+    // Emit error.
+    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
+    Good = false;
+  }
+  BSI->LabelMap.clear();
+  if (!Good)
+    return ExprError();
+
   AnalysisContext AC(BSI->TheDecl);
   CheckFallThroughForBlock(BlockTy, BSI->TheDecl->getBody(), AC);
   CheckUnreachable(AC);
index 7855a7f60935945749a2647fa97cf1b9e4e392fe..f0bbdfe7624ecfe138e84e17722a02a9de07a8e0 100644 (file)
@@ -879,10 +879,6 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
 Action::OwningStmtResult
 Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
                     IdentifierInfo *LabelII) {
-  // If we are in a block, reject all gotos for now.
-  if (CurBlock)
-    return StmtError(Diag(GotoLoc, diag::err_goto_in_block));
-
   // Look up the record for this label identifier.
   LabelStmt *&LabelDecl = getLabelMap()[LabelII];
 
index e9c2341a99c756b93ee23739b46f45c32f0639b8..c303b8417d94228f96b8affc5ae90cdd97e9d8d8 100644 (file)
@@ -33,7 +33,8 @@ void test2() {
         break;  // expected-error {{'break' statement not in loop or switch statement}}
         continue; // expected-error {{'continue' statement not in loop statement}}
         while(1) break;  // ok
-        goto foo; // expected-error {{goto not allowed}}
+        goto foo; // expected-error {{use of undeclared label 'foo'}}
+        a: goto a;       // ok
       });
     break;
   }
index 52cebfe8922f730025273dfda7713d530696230b..1109be6311b0f66e383c9b16de1fa2addbe0d985 100644 (file)
@@ -87,8 +87,7 @@ int test7(void (^p)()) {
 
 void test8() {
 somelabel:
- // FIXME: This should say "jump out of block not legal" when gotos are allowed.
-  ^{ goto somelabel; }();   // expected-error {{goto not allowed in block literal}}
+  ^{ goto somelabel; }();   // expected-error {{use of undeclared label 'somelabel'}}
 }
 
 void test9() {
index 4d3f6cbcf2b846e10d493fc385c51cf882cea15c..74bc7c46f8f5408c698bbba7d65e99b8880cc7fd 100644 (file)
@@ -181,15 +181,14 @@ void test11(int n) {
 // TODO: When and if gotos are allowed in blocks, this should work.
 void test12(int n) {
   void *P = ^{
-    goto L1;  // expected-error {{goto not allowed in block literal}}
+    goto L1;
   L1:
-    goto L2;  // expected-error {{goto not allowed in block literal}}
+    goto L2;
   L2:
-    goto L3;    // expected-error {{goto not allowed in block literal}}
-      // todo-error {{illegal goto into protected scope}}
-    int Arr[n]; // todo-note {{jump bypasses initialization of variable length array}}
+    goto L3;    // expected-error {{illegal goto into protected scope}}
+    int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
   L3:
-    goto L4;  // expected-error {{goto not allowed in block literal}}
+    goto L4;
   L4: return;
   };
 }