]> granicus.if.org Git - clang/commitdiff
Adds recognition of sentinel attribute on block declarations.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 14 May 2009 20:53:39 +0000 (20:53 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 14 May 2009 20:53:39 +0000 (20:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71788 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
test/Sema/sentinel-attribute.c

index 768690aa560f99de94a3fffc3240abaecfe69162..514f94798e51b53e20ec2c8f8910e9c667650177 100644 (file)
@@ -440,7 +440,8 @@ def warn_attribute_weak_import_invalid_on_definition : Warning<
   "'weak_import' attribute cannot be specified on a definition">;
 def warn_attribute_wrong_decl_type : Warning<
   "%0 attribute only applies to %select{function|union|"
-  "variable and function|function or method|parameter|parameter or Objective-C method}1 types">;
+  "variable and function|function or method|parameter|parameter or Objective-C method |"
+  "function, method or block}1 types">;
 def warn_gnu_inline_attribute_requires_inline : Warning<
   "'gnu_inline' attribute requires function to be marked 'inline',"
   " attribute ignored">;
index 7606e84d527014bd703301d7dac6c7084b83c127..7a6a537547e4ee05355ffb4ab60ea79e2023bfb6 100644 (file)
@@ -719,10 +719,32 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     if (!MD->isVariadic()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
       return;
-    }    
+    }
+  } else if (isa<BlockDecl>(d)) {
+    // Note! BlockDecl is typeless. Variadic diagnostics
+    // will be issued by the caller.
+    ;
+  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
+    // FIXME: share code with case of BlockDecl.
+    QualType Ty = V->getType();
+    if (Ty->isBlockPointerType()) {
+      const BlockPointerType *BPT = Ty->getAsBlockPointerType();
+      QualType FnType = BPT->getPointeeType();
+      const FunctionType *FT = FnType->getAsFunctionType();
+      assert(FT && "Block has non-function type?");
+      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
+        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
+        return;
+      }
+    }
+    else {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 6 /*function, method or */;
+      return;
+    }
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << 3 /*function or method*/;
+      << Attr.getName() << 6 /*function, method or */;
     return;
   }
   d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
index 6a7bca0165a65c2d736b5ae74688bae1f6401b25..2bc7461962d7ac26f0f3dd3f1f03958b6e429aa7 100644 (file)
@@ -5038,7 +5038,12 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
 
     CurBlock->hasPrototype = true;
     CurBlock->isVariadic = false;
-    
+    // Check for a valid sentinel attribute on this block.
+    if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+      Diag(ParamInfo.getAttributes()->getLoc(), 
+           diag::warn_attribute_sentinel_not_variadic);
+      // FIXME: remove the attribute.
+    }
     QualType RetTy = T.getTypePtr()->getAsFunctionType()->getResultType();
     
     // Do not allow returning a objc interface by-value.
@@ -5080,6 +5085,13 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
     if ((*AI)->getIdentifier())
       PushOnScopeChains(*AI, CurBlock->TheScope);
 
+  // Check for a valid sentinel attribute on this block.
+  if (!CurBlock->isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+    Diag(ParamInfo.getAttributes()->getLoc(), 
+         diag::warn_attribute_sentinel_not_variadic);
+    // FIXME: remove the attribute.
+  }
+  
   // Analyze the return type.
   QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
   QualType RetTy = T->getAsFunctionType()->getResultType();
index e9451b81bc66e46985f327e706180076ccce7cf4..c40f8df29c3327c01fc1fff52a64a6002f015e14 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang-cc -fsyntax-only -verify %s
-int x __attribute__((sentinel)); //expected-warning{{'sentinel' attribute only applies to function or method types}}
+int x __attribute__((sentinel)); //expected-warning{{'sentinel' attribute only applies to function, method or block types}}
 
 void f1(int a, ...) __attribute__ ((sentinel));
 void f2(int a, ...) __attribute__ ((sentinel(1)));