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'}}
+}
+