[cfe-commits] r70403 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Parse/ParseExpr.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaStmt.cpp test/Sema/block-return.c

Mike Stump mrs at apple.com
Wed Apr 29 12:03:13 PDT 2009


Author: mrs
Date: Wed Apr 29 14:03:13 2009
New Revision: 70403

URL: http://llvm.org/viewvc/llvm-project?rev=70403&view=rev
Log:
Sema and CodeGen support for attributes on blocks.  Radar 6441502

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/Sema/block-return.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 29 14:03:13 2009
@@ -1609,6 +1609,8 @@
   "void %select{function|method}1 %0 should not return void expression">;
 def err_noreturn_function_has_return_expr : Error<
   "function %0 declared 'noreturn' should not return">;
+def err_noreturn_block_has_return_expr : Error<
+  "block declared 'noreturn' should not return">;
 
 def err_shufflevector_non_vector : Error<
   "first two arguments to __builtin_shufflevector must be vectors">;

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Apr 29 14:03:13 2009
@@ -1290,6 +1290,13 @@
   // Parse the block-declarator.
   Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
   ParseDeclarator(DeclaratorInfo);
+
+  if (Tok.is(tok::kw___attribute)) {
+    SourceLocation Loc;
+    AttributeList *AttrList = ParseAttributes(&Loc);
+    DeclaratorInfo.AddAttributes(AttrList, Loc);
+  }
+
   // Inform sema that we are starting a block.
   Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
 }
@@ -1345,6 +1352,13 @@
       Actions.ActOnBlockError(CaretLoc, CurScope);
       return ExprError();
     }
+
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseAttributes(&Loc);
+      ParamInfo.AddAttributes(AttrList, Loc);
+    }
+
     // Inform sema that we are starting a block.
     Actions.ActOnBlockArguments(ParamInfo, CurScope);
   } else if (!Tok.is(tok::l_brace)) {
@@ -1357,6 +1371,13 @@
                                                        false, false, 0, 0,
                                                        CaretLoc, ParamInfo),
                           CaretLoc);
+
+    if (Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseAttributes(&Loc);
+      ParamInfo.AddAttributes(AttrList, Loc);
+    }
+
     // Inform sema that we are starting a block.
     Actions.ActOnBlockArguments(ParamInfo, CurScope);
   }

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Apr 29 14:03:13 2009
@@ -408,10 +408,13 @@
     return false;
   }
 
-  if (!isFunctionOrMethod(d)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << attrName << 0 /*function*/;
-    return false;
+  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
+    ValueDecl *VD = dyn_cast<ValueDecl>(d);
+    if (VD == 0 || !VD->getType()->isBlockPointerType()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+        << attrName << 0 /*function*/;
+      return false;
+    }
   }
   
   return true;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Apr 29 14:03:13 2009
@@ -4773,6 +4773,7 @@
   }
   CurBlock->TheDecl->setParams(Context, &CurBlock->Params[0], 
                                CurBlock->Params.size());
+  ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
 
   for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
        E = CurBlock->TheDecl->param_end(); AI != E; ++AI)

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Apr 29 14:03:13 2009
@@ -707,6 +707,12 @@
 Action::OwningStmtResult
 Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
 
+  if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
+    Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
+      << getCurFunctionOrMethodDecl()->getDeclName();
+    return StmtError();
+  }
+
   // If this is the first return we've seen in the block, infer the type of
   // the block from it.
   if (CurBlock->ReturnType == 0) {

Modified: cfe/trunk/test/Sema/block-return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return.c?rev=70403&r1=70402&r2=70403&view=diff

==============================================================================
--- cfe/trunk/test/Sema/block-return.c (original)
+++ cfe/trunk/test/Sema/block-return.c Wed Apr 29 14:03:13 2009
@@ -95,3 +95,9 @@
 
 int (*funcptr3[5])(long);
 int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block declared as returning an array}}
+
+void foo6() {
+  void (^b)(int) __attribute__((noreturn));
+  b = ^ (int i) __attribute__((noreturn)) { return 1; };  // expected-error {{block declared 'noreturn' should not return}}
+  b(1);
+}





More information about the cfe-commits mailing list