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 | |
| 37 | // CHECK: fix-it:"{{.*}}":{32:11-32:13}:"%ld" |
| 38 | // CHECK: fix-it:"{{.*}}":{32:16-32:16}:"(long)" |
| 39 | |
| 40 | // CHECK: fix-it:"{{.*}}":{33:11-33:13}:"%lu" |
| 41 | // CHECK: fix-it:"{{.*}}":{33:16-33:16}:"(unsigned long)" |
| 42 | |
| 43 | // CHECK: fix-it:"{{.*}}":{34:11-34:13}:"%d" |
| 44 | // CHECK: fix-it:"{{.*}}":{34:16-34:16}:"(int)" |
| 45 | |
| 46 | // CHECK: fix-it:"{{.*}}":{35:11-35:13}:"%u" |
| 47 | // CHECK: fix-it:"{{.*}}":{35:16-35:16}:"(unsigned int)" |
| 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 | |
| 68 | // These cases match the cases in CheckPrintfHandler::checkFormatExpr. |
| 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 | |
| 83 | // CHECK: fix-it:"{{.*}}":{81:11-81:13}:"%ld" |
| 84 | // CHECK: fix-it:"{{.*}}":{81:16-81:16}:"(long)(" |
| 85 | // CHECK: fix-it:"{{.*}}":{81:25-81:25}:")" |
| 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 | |
| 97 | // CHECK-64: fix-it:"{{.*}}":{92:11-92:13}:"%ld" |
| 98 | // CHECK-64: fix-it:"{{.*}}":{92:16-92:16}:"(long)" |
| 99 | |
| 100 | // CHECK-64: fix-it:"{{.*}}":{93:11-93:13}:"%lu" |
| 101 | // CHECK-64: fix-it:"{{.*}}":{93:16-93:16}:"(unsigned long)" |
| 102 | |
| 103 | // CHECK-64: fix-it:"{{.*}}":{94:11-94:14}:"%d" |
| 104 | // CHECK-64: fix-it:"{{.*}}":{94:17-94:17}:"(int)" |
| 105 | |
| 106 | // CHECK-64: fix-it:"{{.*}}":{95:11-95:14}:"%u" |
| 107 | // CHECK-64: fix-it:"{{.*}}":{95:17-95:17}:"(unsigned int)" |
| 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 | |
| 114 | // CHECK-64: fix-it:"{{.*}}":{111:11-111:13}:"%lx" |
| 115 | // CHECK-64: fix-it:"{{.*}}":{111:16-111:16}:"(long)" |
| 116 | |
| 117 | // CHECK-64: fix-it:"{{.*}}":{112:11-112:13}:"%lx" |
| 118 | // CHECK-64: fix-it:"{{.*}}":{112:16-112:16}:"(unsigned long)" |
| 119 | } |
| 120 | |
| 121 | void testNoWarn() { |
| 122 | printf("%ld", getNSInteger()); // no-warning |
| 123 | printf("%lu", getNSUInteger()); // no-warning |
| 124 | printf("%d", getSInt32()); // no-warning |
| 125 | printf("%u", getUInt32()); // no-warning |
| 126 | } |
| 127 | |
| 128 | #else |
| 129 | |
| 130 | void testWarn() { |
| 131 | printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 132 | printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 133 | printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 134 | printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} |
| 135 | |
| 136 | // CHECK-32: fix-it:"{{.*}}":{131:17-131:17}:"(long)" |
| 137 | |
| 138 | // CHECK-32: fix-it:"{{.*}}":{132:17-132:17}:"(unsigned long)" |
| 139 | |
| 140 | // CHECK-32: fix-it:"{{.*}}":{133:16-133:16}:"(int)" |
| 141 | |
| 142 | // CHECK-32: fix-it:"{{.*}}":{134:16-134:16}:"(unsigned int)" |
| 143 | } |
| 144 | |
| 145 | void testPreserveHex() { |
| 146 | printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 147 | printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} |
| 148 | |
| 149 | // CHECK-32: fix-it:"{{.*}}":{146:17-146:17}:"(long)" |
| 150 | |
| 151 | // CHECK-32: fix-it:"{{.*}}":{147:17-147:17}:"(unsigned long)" |
| 152 | } |
| 153 | |
| 154 | void testNoWarn() { |
| 155 | printf("%d", getNSInteger()); // no-warning |
| 156 | printf("%u", getNSUInteger()); // no-warning |
| 157 | printf("%ld", getSInt32()); // no-warning |
| 158 | printf("%lu", getUInt32()); // no-warning |
| 159 | } |
| 160 | |
| 161 | #endif |
| 162 | |
| 163 | |
| 164 | void testCasts() { |
| 165 | printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} |
| 166 | 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}} |
| 167 | printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} |
| 168 | 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}} |
| 169 | |
| 170 | // CHECK: fix-it:"{{.*}}":{165:11-165:13}:"%ld" |
| 171 | // CHECK: fix-it:"{{.*}}":{165:16-165:27}:"(long)" |
| 172 | |
| 173 | // CHECK: fix-it:"{{.*}}":{166:11-166:13}:"%lu" |
| 174 | // CHECK: fix-it:"{{.*}}":{166:16-166:28}:"(unsigned long)" |
| 175 | |
| 176 | // CHECK: fix-it:"{{.*}}":{167:11-167:13}:"%d" |
| 177 | // CHECK: fix-it:"{{.*}}":{167:16-167:24}:"(int)" |
| 178 | |
| 179 | // CHECK: fix-it:"{{.*}}":{168:11-168:13}:"%u" |
| 180 | // CHECK: fix-it:"{{.*}}":{168:16-168:24}:"(unsigned int)" |
| 181 | } |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 182 | |
| 183 | void testCapitals() { |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame^] | 184 | printf("%D", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}} |
| 185 | printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}} |
| 186 | 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] | 187 | |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame^] | 188 | // CHECK: fix-it:"{{.*}}":{184:12-184:13}:"d" |
| 189 | // CHECK: fix-it:"{{.*}}":{185:12-185:13}:"u" |
| 190 | // CHECK: fix-it:"{{.*}}":{186:12-186:13}:"o" |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 191 | |
Jordan Rose | 670941c | 2012-09-13 02:11:15 +0000 | [diff] [blame^] | 192 | |
| 193 | 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'}} |
| 194 | |
| 195 | // FIXME: offering two somewhat-conflicting fixits is less than ideal. |
| 196 | // CHECK: fix-it:"{{.*}}":{193:13-193:14}:"d" |
| 197 | // CHECK: fix-it:"{{.*}}":{193:11-193:14}:"%D" |
Jordan Rose | 275b6f5 | 2012-09-13 02:11:03 +0000 | [diff] [blame] | 198 | } |