summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-12-05 18:44:49 +0000
committerJordan Rose <jordan_rose@apple.com>2012-12-05 18:44:49 +0000
commit0e5badd93b1c6c67bf29b7808f16b15b8d94549d (patch)
treef20773c354a9beb263517071293a8618acf66e22 /clang/test
parentea0fdfe146ac42e90a83a88a796f24ef8e37a2d6 (diff)
downloadbcm5719-llvm-0e5badd93b1c6c67bf29b7808f16b15b8d94549d.tar.gz
bcm5719-llvm-0e5badd93b1c6c67bf29b7808f16b15b8d94549d.zip
Format strings: offer a cast to 'unichar' for %C in Objective-C contexts.
For most cases where a conversion specifier doesn't match an argument, we usually guess that the conversion specifier is wrong. However, if the argument is an integer type and the specifier is %C, it's likely the user really did mean to print the integer as a character. (This is more common than %c because there is no way to specify a unichar literal -- you have to write an integer literal, such as '0x2603', and then cast it to unichar.) This does not change the behavior of %S, since there are fewer cases where printing a literal Unicode *string* is necessary, but this could easily be changed in the future. <rdar://problem/11982013> llvm-svn: 169400
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/FixIt/format.m33
-rw-r--r--clang/test/FixIt/format.mm30
-rw-r--r--clang/test/SemaObjC/format-strings-objc.m6
3 files changed, 66 insertions, 3 deletions
diff --git a/clang/test/FixIt/format.m b/clang/test/FixIt/format.m
index 7957e91ba1e..58c553a0109 100644
--- a/clang/test/FixIt/format.m
+++ b/clang/test/FixIt/format.m
@@ -180,3 +180,36 @@ void multichar_constants_false_negative() {
NSLog(@"%c", 'abcd'); // missing-warning{{format specifies type 'char' but the argument has type 'int'}}
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
}
+
+
+void test_percent_C() {
+ const unsigned short data = 'a';
+ NSLog(@"%C", data); // no-warning
+
+ NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
+
+ typedef unsigned short unichar;
+
+ NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+
+ NSLog(@"%C", data ? 0x2F : 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)("
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:36-[[@LINE-3]]:36}:")"
+
+ NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+
+ NSLog(@"%C", (char)0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:"(unichar)"
+
+ NSLog(@"%C", 'a'); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:"(unichar)"
+}
diff --git a/clang/test/FixIt/format.mm b/clang/test/FixIt/format.mm
new file mode 100644
index 00000000000..64c6c47b9b6
--- /dev/null
+++ b/clang/test/FixIt/format.mm
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck %s
+
+extern "C" void NSLog(id, ...);
+
+void test_percent_C() {
+ const unsigned short data = 'a';
+ NSLog(@"%C", data); // no-warning
+
+ const wchar_t wchar_data = L'a';
+ NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unsigned short)"
+
+ NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
+
+ typedef unsigned short unichar;
+
+ NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unichar)"
+
+ NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+
+ NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+}
diff --git a/clang/test/SemaObjC/format-strings-objc.m b/clang/test/SemaObjC/format-strings-objc.m
index 7faa995002d..bd33ad41a56 100644
--- a/clang/test/SemaObjC/format-strings-objc.m
+++ b/clang/test/SemaObjC/format-strings-objc.m
@@ -145,7 +145,7 @@ void test_percent_S() {
NSLog(@"%S", ptr); // no-warning
const wchar_t* wchar_ptr = L"ab";
- NSLog(@"%S", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}}
+ NSLog(@"%S", wchar_ptr); // expected-warning{{format specifies type 'const unichar *' (aka 'const unsigned short *') but the argument has type 'const wchar_t *'}}
}
void test_percent_ls() {
@@ -154,7 +154,7 @@ void test_percent_ls() {
NSLog(@"%ls", ptr); // no-warning
const wchar_t* wchar_ptr = L"ab";
- NSLog(@"%ls", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}}
+ NSLog(@"%ls", wchar_ptr); // expected-warning{{format specifies type 'const unichar *' (aka 'const unsigned short *') but the argument has type 'const wchar_t *'}}
}
void test_percent_C() {
@@ -162,7 +162,7 @@ void test_percent_C() {
NSLog(@"%C", data); // no-warning
const wchar_t wchar_data = L'a';
- NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'wchar_t'}}
+ NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
}
// Test that %@ works with toll-free bridging (<rdar://problem/10814120>).
OpenPOWER on IntegriCloud