]> granicus.if.org Git - clang/commitdiff
Check format strings when a called function has more than one FormatAttr (one for...
authorTed Kremenek <kremenek@apple.com>
Thu, 9 Sep 2010 04:33:05 +0000 (04:33 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 9 Sep 2010 04:33:05 +0000 (04:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113472 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/format-strings.c

index 1a7bd1d07fc6e8a56773ffaa8e5ede49fb920540..0ed2f33e0e20e988ed99c964b884beaf8110f94b 100644 (file)
@@ -341,8 +341,12 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
   // more efficient. For example, just map function ids to custom
   // handlers.
 
-  // Printf checking.
-  if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
+  // Printf and scanf checking.
+  for (specific_attr_iterator<FormatAttr>
+         i = FDecl->specific_attr_begin<FormatAttr>(),
+         e = FDecl->specific_attr_end<FormatAttr>(); i != e ; ++i) {
+
+    const FormatAttr *Format = *i;
     const bool b = Format->getType() == "scanf";
     if (b || CheckablePrintfAttr(Format, TheCall)) {
       bool HasVAListArg = Format->getFirstArg() == 0;
@@ -353,12 +357,11 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
     }
   }
 
-  specific_attr_iterator<NonNullAttr>
-    i = FDecl->specific_attr_begin<NonNullAttr>(),
-    e = FDecl->specific_attr_end<NonNullAttr>();
-
-  for (; i != e; ++i)
+  for (specific_attr_iterator<NonNullAttr>
+         i = FDecl->specific_attr_begin<NonNullAttr>(),
+         e = FDecl->specific_attr_end<NonNullAttr>(); i != e; ++i) {
     CheckNonNullArguments(*i, TheCall);
+  }
 
   return false;
 }
index 9e8007b9b02d298cad5c563534e7c800a5e07a30..1bfab255313239178f4f9d3ae21c2094d77ec19e 100644 (file)
@@ -302,9 +302,18 @@ void pr7981(wint_t c, wchar_t c2) {
 }
 
 // <rdar://problem/8269537> -Wformat-security says NULL is not a string literal
-void r8269537() {
+void rdar8269537() {
   // This is likely to crash in most cases, but -Wformat-nonliteral technically
   // doesn't warn in this case.
   printf(0); // no-warning
 }
 
+// Handle functions with multiple format attributes.
+extern void rdar8332221_vprintf_scanf(const char *, va_list, const char *, ...)
+     __attribute__((__format__(__printf__, 1, 0)))
+     __attribute__((__format__(__scanf__, 3, 4)));
+     
+void rdar8332221(va_list ap, int *x, long *y) {
+  rdar8332221_vprintf_scanf("%", ap, "%d", x); // expected-warning{{incomplete format specifier}}
+}
+