aboutsummaryrefslogtreecommitdiff
path: root/test/FixIt
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-09-05 22:56:26 +0000
committerJordan Rose <jordan_rose@apple.com>2012-09-05 22:56:26 +0000
commitec08735e1b6a51c11533311b774bf6336c0a5d63 (patch)
tree2914bc2fcf4fa7b9630195f1da15aa6d934b63f6 /test/FixIt
parent614a8656279b6549750e83143635cec63ac0e8b7 (diff)
Format strings: suggest casts for NS(U)Integer and [SU]Int32 on Darwin.
These types are defined differently on 32-bit and 64-bit platforms, and trying to offer a fixit for one platform would only mess up the format string for the other. The Apple-recommended solution is to cast to a type that is known to be large enough and always use that to print the value. This should only have an impact on compile time if the format string is incorrect; in cases where the format string matches the definition on the current platform, no warning will be emitted. <rdar://problem/9135072&12164284> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163266 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/FixIt')
-rw-r--r--test/FixIt/format-darwin.m181
1 files changed, 181 insertions, 0 deletions
diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m
new file mode 100644
index 0000000000..a006d4a8c7
--- /dev/null
+++ b/test/FixIt/format-darwin.m
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s
+
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck %s
+
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck -check-prefix=CHECK-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck -check-prefix=CHECK-64 %s
+
+int printf(const char * restrict, ...);
+
+#if __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef int SInt32;
+typedef unsigned int UInt32;
+
+#else
+
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+typedef long SInt32;
+typedef unsigned long UInt32;
+#endif
+
+NSInteger getNSInteger();
+NSUInteger getNSUInteger();
+SInt32 getSInt32();
+UInt32 getUInt32();
+
+void testCorrectionInAllCases() {
+ printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+ printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
+ printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
+
+ // CHECK: fix-it:"{{.*}}":{32:11-32:13}:"%ld"
+ // CHECK: fix-it:"{{.*}}":{32:16-32:16}:"(long)"
+
+ // CHECK: fix-it:"{{.*}}":{33:11-33:13}:"%lu"
+ // CHECK: fix-it:"{{.*}}":{33:16-33:16}:"(unsigned long)"
+
+ // CHECK: fix-it:"{{.*}}":{34:11-34:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{34:16-34:16}:"(int)"
+
+ // CHECK: fix-it:"{{.*}}":{35:11-35:13}:"%u"
+ // CHECK: fix-it:"{{.*}}":{35:16-35:16}:"(unsigned int)"
+}
+
+@interface Foo {
+@public
+ NSInteger _value;
+}
+- (NSInteger)getInteger;
+
+@property NSInteger value;
+@end
+
+struct Bar {
+ NSInteger value;
+};
+
+
+void testParens(Foo *obj, struct Bar *record) {
+ NSInteger arr[4] = {0};
+ NSInteger i = 0;
+
+ // These cases match the cases in CheckPrintfHandler::checkFormatExpr.
+ printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", obj->_value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", [obj getInteger]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", obj.value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", record->value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", (i ? i : i)); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", *arr); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+ // CHECK-NOT: fix-it:{{.*}}:")"
+
+ printf("%s", i ? i : i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+ // CHECK: fix-it:"{{.*}}":{81:11-81:13}:"%ld"
+ // CHECK: fix-it:"{{.*}}":{81:16-81:16}:"(long)("
+ // CHECK: fix-it:"{{.*}}":{81:25-81:25}:")"
+}
+
+
+#if __LP64__
+
+void testWarn() {
+ printf("%d", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%u", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+ printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
+ printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
+
+ // CHECK-64: fix-it:"{{.*}}":{92:11-92:13}:"%ld"
+ // CHECK-64: fix-it:"{{.*}}":{92:16-92:16}:"(long)"
+
+ // CHECK-64: fix-it:"{{.*}}":{93:11-93:13}:"%lu"
+ // CHECK-64: fix-it:"{{.*}}":{93:16-93:16}:"(unsigned long)"
+
+ // CHECK-64: fix-it:"{{.*}}":{94:11-94:14}:"%d"
+ // CHECK-64: fix-it:"{{.*}}":{94:17-94:17}:"(int)"
+
+ // CHECK-64: fix-it:"{{.*}}":{95:11-95:14}:"%u"
+ // CHECK-64: fix-it:"{{.*}}":{95:17-95:17}:"(unsigned int)"
+}
+
+void testPreserveHex() {
+ printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+
+ // CHECK-64: fix-it:"{{.*}}":{111:11-111:13}:"%lx"
+ // CHECK-64: fix-it:"{{.*}}":{111:16-111:16}:"(long)"
+
+ // CHECK-64: fix-it:"{{.*}}":{112:11-112:13}:"%lx"
+ // CHECK-64: fix-it:"{{.*}}":{112:16-112:16}:"(unsigned long)"
+}
+
+void testNoWarn() {
+ printf("%ld", getNSInteger()); // no-warning
+ printf("%lu", getNSUInteger()); // no-warning
+ printf("%d", getSInt32()); // no-warning
+ printf("%u", getUInt32()); // no-warning
+}
+
+#else
+
+void testWarn() {
+ printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+ printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
+ printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
+
+ // CHECK-32: fix-it:"{{.*}}":{131:17-131:17}:"(long)"
+
+ // CHECK-32: fix-it:"{{.*}}":{132:17-132:17}:"(unsigned long)"
+
+ // CHECK-32: fix-it:"{{.*}}":{133:16-133:16}:"(int)"
+
+ // CHECK-32: fix-it:"{{.*}}":{134:16-134:16}:"(unsigned int)"
+}
+
+void testPreserveHex() {
+ printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+
+ // CHECK-32: fix-it:"{{.*}}":{146:17-146:17}:"(long)"
+
+ // CHECK-32: fix-it:"{{.*}}":{147:17-147:17}:"(unsigned long)"
+}
+
+void testNoWarn() {
+ printf("%d", getNSInteger()); // no-warning
+ printf("%u", getNSUInteger()); // no-warning
+ printf("%ld", getSInt32()); // no-warning
+ printf("%lu", getUInt32()); // no-warning
+}
+
+#endif
+
+
+void testCasts() {
+ printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+ printf("%s", (NSUInteger)0); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
+ printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
+ printf("%s", (UInt32)0); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
+
+ // CHECK: fix-it:"{{.*}}":{165:11-165:13}:"%ld"
+ // CHECK: fix-it:"{{.*}}":{165:16-165:27}:"(long)"
+
+ // CHECK: fix-it:"{{.*}}":{166:11-166:13}:"%lu"
+ // CHECK: fix-it:"{{.*}}":{166:16-166:28}:"(unsigned long)"
+
+ // CHECK: fix-it:"{{.*}}":{167:11-167:13}:"%d"
+ // CHECK: fix-it:"{{.*}}":{167:16-167:24}:"(int)"
+
+ // CHECK: fix-it:"{{.*}}":{168:11-168:13}:"%u"
+ // CHECK: fix-it:"{{.*}}":{168:16-168:24}:"(unsigned int)"
+}