blob: fcc81036fcf394125f47b753d12a969a4ee92b81 [file] [log] [blame]
Jordan Rose4c266aa2012-09-13 02:11:15 +00001// 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 Roseaee34382012-09-05 22:56:26 +00003
Jordan Rosebc53ed12014-05-31 04:12:14 +00004// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-32 %s
5// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-64 %s
Jordan Roseaee34382012-09-05 22:56:26 +00006
7int printf(const char * restrict, ...);
8
9#if __LP64__
Alexander Shaposhnikov62351372017-06-26 23:02:27 +000010typedef long CFIndex;
Jordan Roseaee34382012-09-05 22:56:26 +000011typedef long NSInteger;
12typedef unsigned long NSUInteger;
13typedef int SInt32;
14typedef unsigned int UInt32;
15
16#else
Alexander Shaposhnikov62351372017-06-26 23:02:27 +000017typedef int CFIndex;
Jordan Roseaee34382012-09-05 22:56:26 +000018typedef int NSInteger;
19typedef unsigned int NSUInteger;
20typedef long SInt32;
21typedef unsigned long UInt32;
22#endif
23
Ted Kremenekcd3d4402013-03-25 22:28:37 +000024typedef SInt32 OSStatus;
25
Jordan Rosebc53ed12014-05-31 04:12:14 +000026typedef enum NSIntegerEnum : NSInteger {
27 EnumValueA,
28 EnumValueB
29} NSIntegerEnum;
30
Alexander Shaposhnikov62351372017-06-26 23:02:27 +000031CFIndex getCFIndex();
Jordan Roseaee34382012-09-05 22:56:26 +000032NSInteger getNSInteger();
33NSUInteger getNSUInteger();
34SInt32 getSInt32();
35UInt32 getUInt32();
Jordan Rosebc53ed12014-05-31 04:12:14 +000036NSIntegerEnum getNSIntegerEnum();
Jordan Roseaee34382012-09-05 22:56:26 +000037
38void testCorrectionInAllCases() {
39 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
40 printf("%s", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
41 printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
42 printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
43
Jordan Roseb169ccc2013-01-17 18:47:12 +000044 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
45 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +000046
Jordan Roseb169ccc2013-01-17 18:47:12 +000047 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
48 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +000049
Jordan Roseb169ccc2013-01-17 18:47:12 +000050 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
51 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +000052
Jordan Roseb169ccc2013-01-17 18:47:12 +000053 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
54 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
Jordan Rosebc53ed12014-05-31 04:12:14 +000055
56 printf("%s", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
57
58 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
59 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Alexander Shaposhnikov62351372017-06-26 23:02:27 +000060
61 printf("%s", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
62
63 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
64 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +000065}
66
67@interface Foo {
68@public
69 NSInteger _value;
70}
71- (NSInteger)getInteger;
72
73@property NSInteger value;
74@end
75
76struct Bar {
77 NSInteger value;
78};
79
80
81void testParens(Foo *obj, struct Bar *record) {
82 NSInteger arr[4] = {0};
83 NSInteger i = 0;
84
Jordan Roseea0fdfe2012-12-05 18:44:44 +000085 // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr.
Jordan Roseaee34382012-09-05 22:56:26 +000086 printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
87 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
88 printf("%s", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
89 printf("%s", obj->_value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
90 printf("%s", [obj getInteger]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
91 printf("%s", obj.value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
92 printf("%s", record->value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
Anton Korobeynikov50a3cbd2014-11-12 23:15:38 +000093 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}}
Jordan Roseaee34382012-09-05 22:56:26 +000094 printf("%s", *arr); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
95
96 // CHECK-NOT: fix-it:{{.*}}:")"
97
Anton Korobeynikov50a3cbd2014-11-12 23:15:38 +000098 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}}
Jordan Roseaee34382012-09-05 22:56:26 +000099
Jordan Roseb169ccc2013-01-17 18:47:12 +0000100 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
101 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)("
102 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"
Jordan Roseaee34382012-09-05 22:56:26 +0000103}
104
105
106#if __LP64__
107
108void testWarn() {
109 printf("%d", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
110 printf("%u", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
111 printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
112 printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
113
Jordan Roseb169ccc2013-01-17 18:47:12 +0000114 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
115 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000116
Jordan Roseb169ccc2013-01-17 18:47:12 +0000117 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
118 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000119
Jordan Roseb169ccc2013-01-17 18:47:12 +0000120 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d"
121 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000122
Jordan Roseb169ccc2013-01-17 18:47:12 +0000123 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u"
124 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)"
Jordan Rosebc53ed12014-05-31 04:12:14 +0000125
126 printf("%d", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
127
128 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
129 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Alexander Shaposhnikov62351372017-06-26 23:02:27 +0000130
131 printf("%d", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
132
133 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
134 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000135}
136
137void testPreserveHex() {
138 printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
139 printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
140
Jordan Roseb169ccc2013-01-17 18:47:12 +0000141 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx"
142 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000143
Jordan Roseb169ccc2013-01-17 18:47:12 +0000144 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%lx"
145 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000146}
147
Jordan Roseaa7a3b32013-01-17 18:47:16 +0000148void testSignedness(NSInteger i, NSUInteger u) {
149 printf("%d", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
150 printf("%i", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
151 printf("%u", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
152
153 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
154 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
155 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld"
156}
157
Jordan Roseaee34382012-09-05 22:56:26 +0000158void testNoWarn() {
159 printf("%ld", getNSInteger()); // no-warning
160 printf("%lu", getNSUInteger()); // no-warning
161 printf("%d", getSInt32()); // no-warning
162 printf("%u", getUInt32()); // no-warning
Jordan Rosebc53ed12014-05-31 04:12:14 +0000163 printf("%ld", getNSIntegerEnum()); // no-warning
Jordan Roseaee34382012-09-05 22:56:26 +0000164}
165
166#else
167
168void testWarn() {
169 printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
170 printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
171 printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
172 printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
173
Jordan Roseb169ccc2013-01-17 18:47:12 +0000174 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(long)"
175 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)"
176 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)"
177 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)"
Jordan Rosebc53ed12014-05-31 04:12:14 +0000178
179 printf("%ld", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
180
181 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
Alexander Shaposhnikov62351372017-06-26 23:02:27 +0000182
183 printf("%ld", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
184
185 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000186}
187
188void testPreserveHex() {
189 printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
190 printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
191
Jordan Roseb169ccc2013-01-17 18:47:12 +0000192 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(long)"
193 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000194}
195
196void testNoWarn() {
197 printf("%d", getNSInteger()); // no-warning
198 printf("%u", getNSUInteger()); // no-warning
199 printf("%ld", getSInt32()); // no-warning
200 printf("%lu", getUInt32()); // no-warning
Jordan Rosebc53ed12014-05-31 04:12:14 +0000201 printf("%d", getNSIntegerEnum()); // no-warning
Jordan Roseaee34382012-09-05 22:56:26 +0000202}
203
Jordan Roseaa7a3b32013-01-17 18:47:16 +0000204void testSignedness(NSInteger i, NSUInteger u) {
205 // It is valid to use a specifier with the opposite signedness as long as
206 // the type is correct.
207 printf("%d", u); // no-warning
208 printf("%i", u); // no-warning
209 printf("%u", i); // no-warning
210}
211
Jordan Roseaee34382012-09-05 22:56:26 +0000212#endif
213
214
215void testCasts() {
216 printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
217 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}}
218 printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
219 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}}
220
Jordan Roseb169ccc2013-01-17 18:47:12 +0000221 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
222 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000223
Jordan Roseb169ccc2013-01-17 18:47:12 +0000224 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
225 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000226
Jordan Roseb169ccc2013-01-17 18:47:12 +0000227 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
228 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000229
Jordan Roseb169ccc2013-01-17 18:47:12 +0000230 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
231 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
Jordan Rosebc53ed12014-05-31 04:12:14 +0000232
233 printf("%s", (NSIntegerEnum)0); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
234
235 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
236 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:31}:"(long)"
Alexander Shaposhnikov62351372017-06-26 23:02:27 +0000237
238 printf("%s", (CFIndex)0); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
239
240 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
241 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:25}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000242}
Jordan Rose510260c2012-09-13 02:11:03 +0000243
244void testCapitals() {
Jordan Rose4c266aa2012-09-13 02:11:15 +0000245 printf("%D", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}}
246 printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}}
247 printf("%O", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'o'?}}
Jordan Rose510260c2012-09-13 02:11:03 +0000248
Jordan Roseb169ccc2013-01-17 18:47:12 +0000249 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"d"
250 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"u"
251 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"o"
Jordan Rose510260c2012-09-13 02:11:03 +0000252
Jordan Rose4c266aa2012-09-13 02:11:15 +0000253
254 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'}}
255
256 // FIXME: offering two somewhat-conflicting fixits is less than ideal.
Jordan Roseb169ccc2013-01-17 18:47:12 +0000257 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
258 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
Jordan Rose510260c2012-09-13 02:11:03 +0000259}
Ted Kremenekcd3d4402013-03-25 22:28:37 +0000260
261void testLayeredTypedefs(OSStatus i) {
262 printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}}
Ted Kremenek30b77bf2013-03-25 23:05:40 +0000263 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
Ted Kremenekcd3d4402013-03-25 22:28:37 +0000264}
265