]> granicus.if.org Git - clang/commitdiff
Fix rdar://6719156 - clang should emit a better error when blocks are disabled but...
authorChris Lattner <sabre@nondot.org>
Fri, 27 Mar 2009 04:18:06 +0000 (04:18 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 27 Mar 2009 04:18:06 +0000 (04:18 +0000)
by changing blocks from being disabled in the parser to being disabled
in Sema.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67816 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaType.cpp
test/Sema/exprs.c

index 5dbc3d0ce84cfc46ee9b6c781898dbaaa8d2b7ff..62647ff51c555c3005044002e3213938d4e189c6 100644 (file)
@@ -1394,6 +1394,8 @@ def warn_stringcompare : Warning<
 
 
 // Blocks
+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">;
index a9fbbbe4981f1fabc95b8bc2fa20b09eb43142df..2c26b13dc14fedfccdf83147c39b10073ede5aee 100644 (file)
@@ -1682,11 +1682,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
 
   tok::TokenKind Kind = Tok.getKind();
   // Not a pointer, C++ reference, or block.
-  if (Kind != tok::star &&
+  if (Kind != tok::star && Kind != tok::caret &&
       (Kind != tok::amp || !getLang().CPlusPlus) &&
       // We parse rvalue refs in C++03, because otherwise the errors are scary.
-      (Kind != tok::ampamp || !getLang().CPlusPlus) &&
-      (Kind != tok::caret || !getLang().Blocks)) {
+      (Kind != tok::ampamp || !getLang().CPlusPlus)) {
     if (DirectDeclParser)
       (this->*DirectDeclParser)(D);
     return;
@@ -1697,7 +1696,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
   SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
   D.SetRangeEnd(Loc);
 
-  if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
+  if (Kind == tok::star || Kind == tok::caret) {
     // Is a pointer.
     DeclSpec DS;
 
index c0b28775ceeb892e90d131b4a5fff4d00f0cc1db..913f9baff193672db3fba55e38628b7d43fefe78 100644 (file)
@@ -776,10 +776,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
     return ParseObjCAtExpression(AtLoc);
   }
   case tok::caret:
-    if (getLang().Blocks)
-      return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
-    Diag(Tok, diag::err_expected_expression);
-    return ExprError();
+    return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
   case tok::l_square:
     // These can be followed by postfix-expr pieces.
     if (getLang().ObjC1)
@@ -1344,18 +1341,17 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
 
 
   OwningExprResult Result(Actions, true);
-  if (Tok.is(tok::l_brace)) {
-    OwningStmtResult Stmt(ParseCompoundStatementBody());
-    if (!Stmt.isInvalid()) {
-      Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope);
-    } else {
-      Actions.ActOnBlockError(CaretLoc, CurScope);
-    }
-  } else {
+  if (!Tok.is(tok::l_brace)) {
     // Saw something like: ^expr
     Diag(Tok, diag::err_expected_expression);
     return ExprError();
   }
+  
+  OwningStmtResult Stmt(ParseCompoundStatementBody());
+  if (!Stmt.isInvalid())
+    Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope);
+  else
+    Actions.ActOnBlockError(CaretLoc, CurScope);
   return move(Result);
 }
 
index 176529ce9c536bc4e4f4f16c0331f0e95867ae66..2cca2cdb1e10d3933b82f1769b7aaaf8e22e54ce 100644 (file)
@@ -405,14 +405,13 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
     if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
       TryAnnotateCXXScopeToken();
 
-    if (Tok.is(tok::star) || Tok.is(tok::amp) ||
-        (Tok.is(tok::caret) && getLang().Blocks) ||
+    if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
         (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
       // ptr-operator
       ConsumeToken();
       while (Tok.is(tok::kw_const)    ||
              Tok.is(tok::kw_volatile) ||
-             Tok.is(tok::kw_restrict)   )
+             Tok.is(tok::kw_restrict))
         ConsumeToken();
     } else {
       break;
index 92a4de08e4a571dc713bb6d5fd7b9ec01eb1fb11..8922abd20b9a7c23cde7947f4da44cd82caad7b0 100644 (file)
@@ -4589,6 +4589,10 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
 /// literal was successfully completed.  ^(int x){...}
 Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
                                                 StmtArg body, Scope *CurScope) {
+  // If blocks are disabled, emit an error.
+  if (!LangOpts.Blocks)
+    Diag(CaretLoc, diag::err_blocks_disable);
+  
   // Ensure that CurBlock is deleted.
   llvm::OwningPtr<BlockSemaInfo> BSI(CurBlock);
 
index f14eb6520324a556df39a989728ed7cc0190597d..dbe19e3434c8e7c8d764f7a56a9f6bcd834bc9d9 100644 (file)
@@ -625,6 +625,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
     switch (DeclType.Kind) {
     default: assert(0 && "Unknown decltype!");
     case DeclaratorChunk::BlockPointer:
+      // If blocks are disabled, emit an error.
+      if (!LangOpts.Blocks)
+        Diag(DeclType.Loc, diag::err_blocks_disable);
+        
       if (DeclType.Cls.TypeQuals)
         Diag(D.getIdentifierLoc(), diag::err_qualified_block_pointer_type);
       if (!T.getTypePtr()->isFunctionType())
index d348d9e190d6cc944d58e07c01fe1902313f2228..80334078f1f3f1017a2f532caa0f3ea44a805cb1 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang-cc %s -verify -pedantic -fsyntax-only
+// RUN: clang-cc %s -verify -pedantic -fsyntax-only -fno-blocks
 
 // PR1966
 _Complex double test1() {
@@ -85,3 +85,9 @@ int test12(const char *X) {
   return X == "foo";  // expected-warning {{comparison against a string literal is unspecified}}
 }
 
+// rdar://6719156
+void test13(
+            void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}}
+  P();
+  P = ^(){}; // expected-error {{blocks support disabled - compile with -fblocks}}
+}