[cfe-commits] r71888 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaExpr.cpp test/Sema/block-sentinel-attribute.c test/Sema/function-pointer-sentinel-attribute.c

Fariborz Jahanian fjahanian at apple.com
Fri May 15 13:33:25 PDT 2009


Author: fjahanian
Date: Fri May 15 15:33:25 2009
New Revision: 71888

URL: http://llvm.org/viewvc/llvm-project?rev=71888&view=rev
Log:
This patch finishes off the sentinel attribute handling for
blocks and function pointers.

Added:
    cfe/trunk/test/Sema/block-sentinel-attribute.c
    cfe/trunk/test/Sema/function-pointer-sentinel-attribute.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 15 15:33:25 2009
@@ -799,9 +799,9 @@
 def warn_not_enough_argument : Warning<
   "not enough variable arguments in %0 declaration to fit a sentinel">;
 def warn_missing_sentinel : Warning <
-  "missing sentinel in %select{function|method}0 %select{call|dispatch}1">;
+  "missing sentinel in %select{function call|method dispatch|block call}0">;
 def note_sentinel_here : Note<
-  "%select{function|method}0 has been explicitly marked sentinel here">;
+  "%select{function|method|block}0 has been explicitly marked sentinel here">;
 def warn_missing_prototype : Warning<
   "no previous prototype for function %0">,
   InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri May 15 15:33:25 2009
@@ -726,11 +726,9 @@
     ;
   } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
     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 (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
+      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 
+        : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType();
       if (!cast<FunctionProtoType>(FT)->isVariadic()) {
         S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
         return;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May 15 15:33:25 2009
@@ -130,6 +130,30 @@
     }
     warnNotEnoughArgs = (P != E || i >= NumArgs);
   }
+  else if (VarDecl *V = dyn_cast<VarDecl>(D)) {
+    // block or function pointer call.
+    QualType Ty = V->getType();
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
+      const FunctionType *FT = Ty->isFunctionPointerType() 
+      ? Ty->getAsPointerType()->getPointeeType()->getAsFunctionType()
+      : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType();
+      if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) {
+        unsigned NumArgsInProto = Proto->getNumArgs();
+        unsigned k;
+        for (k = 0; (k != NumArgsInProto && i < NumArgs); k++) {
+          if (nullPos)
+            --nullPos;
+          else
+            ++i;
+        }
+        warnNotEnoughArgs = (k != NumArgsInProto || i >= NumArgs);
+      }
+      if (Ty->isBlockPointerType())
+        isMethod = 2;
+    }
+    else
+      return;
+  }
   else
     return;
 
@@ -155,7 +179,7 @@
   Expr *sentinelExpr = Args[sentinel];
   if (sentinelExpr && (!sentinelExpr->getType()->isPointerType() ||
                        !sentinelExpr->isNullPointerConstant(Context))) {
-    Diag(Loc, diag::warn_missing_sentinel) << isMethod << isMethod;
+    Diag(Loc, diag::warn_missing_sentinel) << isMethod;
     Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
   }
   return;
@@ -2466,6 +2490,7 @@
   Expr **Args = reinterpret_cast<Expr**>(args.release());
   assert(Fn && "no function call expression");
   FunctionDecl *FDecl = NULL;
+  NamedDecl *NDecl = NULL;
   DeclarationName UnqualifiedName;
 
   if (getLangOptions().CPlusPlus) {
@@ -2531,6 +2556,7 @@
   if (DRExpr) {
     FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
     Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
+    NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
   }
 
   if (Ovl || (getLangOptions().CPlusPlus && (FDecl || UnqualifiedName))) {
@@ -2638,11 +2664,12 @@
       return ExprError(Diag(LParenLoc, diag::err_member_call_without_object)
         << Fn->getSourceRange());
 
+  // Check for sentinels
+  if (NDecl)
+    DiagnoseSentinelCalls(NDecl, LParenLoc, Args, NumArgs);
   // Do special checking on direct calls to functions.
-  if (FDecl) {
-    DiagnoseSentinelCalls(FDecl, LParenLoc, Args, NumArgs);
+  if (FDecl)
     return CheckFunctionCall(FDecl, TheCall.take());
-  }
 
   return Owned(TheCall.take());
 }

Added: cfe/trunk/test/Sema/block-sentinel-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-sentinel-attribute.c?rev=71888&view=auto

==============================================================================
--- cfe/trunk/test/Sema/block-sentinel-attribute.c (added)
+++ cfe/trunk/test/Sema/block-sentinel-attribute.c Fri May 15 15:33:25 2009
@@ -0,0 +1,24 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+void (^e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1)));
+
+int main()
+{
+        void (^b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)) =  // expected-note {{block has been explicitly marked sentinel here}}
+						^ __attribute__ ((__sentinel__)) (int arg, const char * format, ...) {};
+        void (^z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))) = ^ __attribute__ ((__sentinel__ (2))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}}
+
+
+        void (^y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))) = ^ __attribute__ ((__sentinel__ (5))) (int arg, const char * format, ...) {}; // expected-note {{block has been explicitly marked sentinel here}}
+
+	b(1, "%s", (void*)0);	// OK
+	b(1, "%s", 0);  // expected-warning {{missing sentinel in block call}}
+	z(1, "%s",4 ,1,0);  // expected-warning {{missing sentinel in block call}}
+	z(1, "%s", (void*)0, 1, 0);	// OK
+
+	y(1, "%s", 1,2,3,4,5,6,7);  // expected-warning {{missing sentinel in block call}}
+
+	y(1, "%s", (void*)0,3,4,5,6,7);	// OK
+
+}
+

Added: cfe/trunk/test/Sema/function-pointer-sentinel-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function-pointer-sentinel-attribute.c?rev=71888&view=auto

==============================================================================
--- cfe/trunk/test/Sema/function-pointer-sentinel-attribute.c (added)
+++ cfe/trunk/test/Sema/function-pointer-sentinel-attribute.c Fri May 15 15:33:25 2009
@@ -0,0 +1,23 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+void (*e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1)));
+
+int main()
+{
+        void (*b) (int arg, const char * format, ...) __attribute__ ((__sentinel__));  // expected-note {{function has been explicitly marked sentinel here}}
+        void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))); // expected-note {{function has been explicitly marked sentinel here}}
+
+
+        void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))); // expected-note {{function has been explicitly marked sentinel here}}
+
+	b(1, "%s", (void*)0);	// OK
+	b(1, "%s", 0);  // expected-warning {{missing sentinel in function call}}
+	z(1, "%s",4 ,1,0);  // expected-warning {{missing sentinel in function call}}
+	z(1, "%s", (void*)0, 1, 0);	// OK
+
+	y(1, "%s", 1,2,3,4,5,6,7);  // expected-warning {{missing sentinel in function call}}
+
+	y(1, "%s", (void*)0,3,4,5,6,7);	// OK
+
+}
+





More information about the cfe-commits mailing list