Add basic type checking of format string conversion specifiers and their arguments.  Thanks to Cristian Draghici for his help with this patch!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94864 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 94fb593..f1ab868 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -71,8 +71,8 @@
 {
   printf("%s%lb%d","unix",10,20); // expected-warning {{invalid conversion specifier 'b'}}
   fprintf(fp,"%%%l"); // expected-warning {{incomplete format specifier}}
-  sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // no-warning
-  snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning {{invalid conversion specifier ';'}}
+  sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // expected-warning{{conversion specifies type 'long' but the argument has type 'int'}}
+  snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning{{conversion specifies type 'long' but the argument has type 'int'}} expected-warning {{invalid conversion specifier ';'}}
 }
 
 void check_null_char_string(char* b)
@@ -162,3 +162,11 @@
   printf("%.", x);  // expected-warning{{incomplete format specifier}}
 } 
 
+typedef struct __aslclient *aslclient;
+typedef struct __aslmsg *aslmsg;
+int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));
+void test_asl(aslclient asl) {
+  // Test case from <rdar://problem/7341605>.
+  asl_log(asl, 0, 3, "Error: %m"); // no-warning
+  asl_log(asl, 0, 3, "Error: %W"); // expected-warning{{invalid conversion specifier 'W'}}
+}
diff --git a/test/Sema/ucn-cstring.c b/test/Sema/ucn-cstring.c
index f5bf457..ac1d37f 100644
--- a/test/Sema/ucn-cstring.c
+++ b/test/Sema/ucn-cstring.c
@@ -5,8 +5,8 @@
 int main(void) {
   int a[sizeof("hello \u2192 \u2603 \u2190 world") == 24 ? 1 : -1];
   
-  printf("%s (%d)\n", "hello \u2192 \u2603 \u2190 world", sizeof("hello \u2192 \u2603 \u2190 world"));
-  printf("%s (%d)\n", "\U00010400\U0001D12B", sizeof("\U00010400\U0001D12B"));
+  printf("%s (%zd)\n", "hello \u2192 \u2603 \u2190 world", sizeof("hello \u2192 \u2603 \u2190 world"));
+  printf("%s (%zd)\n", "\U00010400\U0001D12B", sizeof("\U00010400\U0001D12B"));
   // Some error conditions...
   printf("%s\n", "\U"); // expected-error{{\u used with no following hex digits}}
   printf("%s\n", "\U00"); // expected-error{{incomplete universal character name}}