Extend format specifier checking to include field function pointers in addition to...
authorAaron Ballman <aaron@aaronballman.com>
Thu, 23 Apr 2015 16:14:19 +0000 (16:14 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Thu, 23 Apr 2015 16:14:19 +0000 (16:14 +0000)
llvm-svn: 235606

clang/lib/Sema/SemaChecking.cpp
clang/test/SemaCXX/format-strings.cpp

index 05eaaec..fd91c77 100644 (file)
@@ -1289,11 +1289,14 @@ bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac,
 
 bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
                             const FunctionProtoType *Proto) {
-  const VarDecl *V = dyn_cast<VarDecl>(NDecl);
-  if (!V)
+  QualType Ty;
+  if (const auto *V = dyn_cast<VarDecl>(NDecl))
+    Ty = V->getType();
+  else if (const auto *F = dyn_cast<FieldDecl>(NDecl))
+    Ty = F->getType();
+  else
     return false;
 
-  QualType Ty = V->getType();
   if (!Ty->isBlockPointerType() && !Ty->isFunctionPointerType())
     return false;
 
index 4177570..fa7251d 100644 (file)
@@ -133,3 +133,18 @@ namespace Templates {
   }
 }
 
+namespace implicit_this_tests {
+struct t {
+    void func1(const char *, ...) __attribute__((__format__(printf, 1, 2))); // expected-error {{format attribute cannot specify the implicit this argument as the format string}}
+    void (*func2)(const char *, ...) __attribute__((__format__(printf, 1, 2)));
+    static void (*func3)(const char *, ...) __attribute__((__format__(printf, 1, 2)));
+    static void func4(const char *, ...) __attribute__((__format__(printf, 1, 2)));
+};
+
+void f() {
+  t t1;
+  t1.func2("Hello %s"); // expected-warning {{more '%' conversions than data arguments}}
+  t::func3("Hello %s"); // expected-warning {{more '%' conversions than data arguments}}
+  t::func4("Hello %s"); // expected-warning {{more '%' conversions than data arguments}}
+}
+}