]> granicus.if.org Git - clang/commitdiff
Sema and CodeGen support for attributes on blocks. Radar 6441502
authorMike Stump <mrs@apple.com>
Wed, 29 Apr 2009 19:03:13 +0000 (19:03 +0000)
committerMike Stump <mrs@apple.com>
Wed, 29 Apr 2009 19:03:13 +0000 (19:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70403 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 6fcdff96e0dda51cf83cf4bbbdf74d3fdbef3ace..6604ddef36256f0b8fbe5329a6b083b9d403e1c6 100644 (file)
@@ -1609,6 +1609,8 @@ def ext_return_has_void_expr : Extension<
   "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">;
index f299c5246ec675eeb633694e43dc76b149ad58ab..1f37532d718bec0bf93952ac1a792bcf02a5f44a 100644 (file)
@@ -1290,6 +1290,13 @@ void Parser::ParseBlockId() {
   // 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 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
       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 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
                                                        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);
   }
index 9e550ba44f61d05e61d812d6dbcac0906564755e..2df4e36cc9544be4121be44107dc3e306a9c63d3 100644 (file)
@@ -408,10 +408,13 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
     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;
index dcc0311f6042e8760c36da7de24d5678d8f68a8c..5d16d77f9f66c9cacecca15ba7c17d63df5164dd 100644 (file)
@@ -4773,6 +4773,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
   }
   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)
index 311496c720e66445a546a1c42c87be2a6966b18a..e44aeb75575e1e67baee3dac8b4f605cb93cc73f 100644 (file)
@@ -707,6 +707,12 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
 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) {
index 4b0dbb0b013faa39cde10260ee2cd7c4706d741e..4a32a97a5decf9416b2762bdd36d05d91d0f6250 100644 (file)
@@ -95,3 +95,9 @@ bptr foo5(int j) {
 
 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);
+}