Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s |
| 2 | // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 3 | |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame] | 4 | // RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s |
| 5 | // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 6 | |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame] | 7 | // RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-32 %s |
| 8 | // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-64 %s |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 9 | |
| 10 | int printf(const char * restrict, ...); |
| 11 | |
| 12 | #if __LP64__ |
| 13 | typedef long NSInteger; |
| 14 | typedef unsigned long NSUInteger; |
| 15 | typedef int SInt32; |
| 16 | typedef unsigned int UInt32; |
| 17 | |
| 18 | #else |
| 19 | |
| 20 | typedef int NSInteger; |
| 21 | typedef unsigned int NSUInteger; |
| 22 | typedef long SInt32; |
| 23 | typedef unsigned long UInt32; |
| 24 | #endif |
| 25 | |
| 26 | NSInteger getNSInteger(); |
| 27 | NSUInteger getNSUInteger(); |
| 28 | SInt32 getSInt32(); |
| 29 | UInt32 getUInt32(); |
| 30 | |
| 31 | void testCorrectionInAllCases() { |
| 32 | printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 33 | printf("%s", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 34 | printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 35 | printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} |
| 36 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 37 | // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" |
| 38 | // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 39 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 40 | // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" |
| 41 | // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 42 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 43 | // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d" |
| 44 | // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 45 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 46 | // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u" |
| 47 | // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | @interface Foo { |
| 51 | @public |
| 52 | NSInteger _value; |
| 53 | } |
| 54 | - (NSInteger)getInteger; |
| 55 | |
| 56 | @property NSInteger value; |
| 57 | @end |
| 58 | |
| 59 | struct Bar { |
| 60 | NSInteger value; |
| 61 | }; |
| 62 | |
| 63 | |
| 64 | void testParens(Foo *obj, struct Bar *record) { |
| 65 | NSInteger arr[4] = {0}; |
| 66 | NSInteger i = 0; |
| 67 | |
Jordan Rose | 17ddc54 | 2012-12-05 18:44:44 +0000 | [diff] [blame] | 68 | // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr. |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 69 | printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 70 | printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 71 | printf("%s", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 72 | printf("%s", obj->_value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 73 | printf("%s", [obj getInteger]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 74 | printf("%s", obj.value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 75 | printf("%s", record->value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 76 | 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}} |
| 77 | printf("%s", *arr); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 78 | |
| 79 | // CHECK-NOT: fix-it:{{.*}}:")" |
| 80 | |
| 81 | 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}} |
| 82 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 83 | // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld" |
| 84 | // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)(" |
| 85 | // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | |
| 89 | #if __LP64__ |
| 90 | |
| 91 | void testWarn() { |
| 92 | printf("%d", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 93 | printf("%u", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 94 | printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 95 | printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} |
| 96 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 97 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" |
| 98 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 99 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 100 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" |
| 101 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 102 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 103 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d" |
| 104 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 105 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 106 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u" |
| 107 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | void testPreserveHex() { |
| 111 | printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 112 | printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 113 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 114 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx" |
| 115 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 116 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 117 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%lx" |
| 118 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(unsigned long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 119 | } |
| 120 | |
Jordan Rose | 242ae3d | 2013-01-17 18:47:16 +0000 | [diff] [blame] | 121 | void testSignedness(NSInteger i, NSUInteger u) { |
| 122 | printf("%d", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 123 | printf("%i", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 124 | printf("%u", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 125 | |
| 126 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" |
| 127 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" |
| 128 | // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld" |
| 129 | } |
| 130 | |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 131 | void testNoWarn() { |
| 132 | printf("%ld", getNSInteger()); // no-warning |
| 133 | printf("%lu", getNSUInteger()); // no-warning |
| 134 | printf("%d", getSInt32()); // no-warning |
| 135 | printf("%u", getUInt32()); // no-warning |
| 136 | } |
| 137 | |
| 138 | #else |
| 139 | |
| 140 | void testWarn() { |
| 141 | printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 142 | printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 143 | printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 144 | printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} |
| 145 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 146 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(long)" |
| 147 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)" |
| 148 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)" |
| 149 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | void testPreserveHex() { |
| 153 | printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 154 | printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 155 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 156 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(long)" |
| 157 | // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(unsigned long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | void testNoWarn() { |
| 161 | printf("%d", getNSInteger()); // no-warning |
| 162 | printf("%u", getNSUInteger()); // no-warning |
| 163 | printf("%ld", getSInt32()); // no-warning |
| 164 | printf("%lu", getUInt32()); // no-warning |
| 165 | } |
| 166 | |
Jordan Rose | 242ae3d | 2013-01-17 18:47:16 +0000 | [diff] [blame] | 167 | void testSignedness(NSInteger i, NSUInteger u) { |
| 168 | // It is valid to use a specifier with the opposite signedness as long as |
| 169 | // the type is correct. |
| 170 | printf("%d", u); // no-warning |
| 171 | printf("%i", u); // no-warning |
| 172 | printf("%u", i); // no-warning |
| 173 | } |
| 174 | |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 175 | #endif |
| 176 | |
| 177 | |
| 178 | void testCasts() { |
| 179 | printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 180 | 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}} |
| 181 | printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 182 | 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}} |
| 183 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 184 | // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" |
| 185 | // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 186 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 187 | // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" |
| 188 | // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 189 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 190 | // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d" |
| 191 | // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 192 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 193 | // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u" |
| 194 | // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)" |
Jordan Rose | ec08735 | 2012-09-05 22:56:26 +0000 | [diff] [blame] | 195 | } |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 196 | |
| 197 | void testCapitals() { |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame] | 198 | printf("%D", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}} |
| 199 | printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}} |
| 200 | printf("%O", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'o'?}} |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 201 | |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 202 | // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"d" |
| 203 | // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"u" |
| 204 | // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"o" |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 205 | |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame] | 206 | |
| 207 | printf("%lD", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}} expected-warning{{format specifies type 'long' but the argument has type 'int'}} |
| 208 | |
| 209 | // FIXME: offering two somewhat-conflicting fixits is less than ideal. |
Jordan Rose | c8145bb | 2013-01-17 18:47:12 +0000 | [diff] [blame] | 210 | // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d" |
| 211 | // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D" |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 212 | } |