Teach format string checking about compile-time CFString constants.

Within the guts of CheckFormatHandler, the IsObjCLiteral flag was being used in
two ways: to see if null bytes were allowed, and to see if the '%@' specifier
is allowed.* The former usage has been changed to an explicit test and the
latter pushed down to CheckPrintfHandler and renamed ObjCContext, since it
applies to CFStrings as well.

* This also changes how wide chars are interpreted; in OS X Foundation, the
wide character type is 'unichar', a typedef for short, rather than wchar_t.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157968 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index c1285b2..043cb5d 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -31,6 +31,12 @@
 
 typedef const struct __CFString * CFStringRef;
 extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2)));
+#define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
+
+// This function is used instead of the builtin if -fno-constant-cfstrings.
+// The definition on Mac OS X is NOT annotated with format_arg as of 10.7,
+// but if it were, we want the same checking behavior as with the builtin.
+extern CFStringRef __CFStringMakeConstantString(const char *) __attribute__((format_arg(1)));
 
 int printf(const char * restrict, ...) ;
 
@@ -52,6 +58,7 @@
   long long test = 500;  
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
+  CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
 }
 
 // <rdar://problem/7697748>
@@ -72,7 +79,7 @@
 
 void check_mylog() {
   MyNSLog(@"%@"); // expected-warning {{more '%' conversions than data arguments}}
-  // FIXME: find a way to test CFString too, but I don't know how to create constant CFString.
+  MyCFStringCreateWithFormat(CFSTR("%@")); // expected-warning {{more '%' conversions than data arguments}}
 }
 
 // PR 10275 - format function attribute isn't checked in Objective-C methods
@@ -159,8 +166,12 @@
 }
 
 // Test that %@ works with toll-free bridging (<rdar://problem/10814120>).
-void test_toll_free_bridging(CFStringRef x) {
+void test_toll_free_bridging(CFStringRef x, id y) {
   NSLog(@"%@", x); // no-warning
+  CFStringCreateWithFormat(CFSTR("%@"), x); // no-warning
+
+  NSLog(@"%@", y); // no-warning
+  CFStringCreateWithFormat(CFSTR("%@"), y); // no-warning
 }
 
 @interface Bar
@@ -195,3 +206,7 @@
   printf("%p", x);  // no-warning
 }
 
+void test_nonBuiltinCFStrings() {
+  CFStringCreateWithFormat(__CFStringMakeConstantString("%@"), 1); // expected-warning{{format specifies type 'id' but the argument has type 'int'}}
+}
+