blob: 170bb09fb90473d411a57261c26e19dfe0ab49e6 [file] [log] [blame]
Jordan Rose670941c2012-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 Roseec087352012-09-05 22:56:26 +00003
Stephen Hinesc568f1e2014-07-21 00:47:37 -07004// 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 Roseec087352012-09-05 22:56:26 +00006
7int printf(const char * restrict, ...);
8
9#if __LP64__
10typedef long NSInteger;
11typedef unsigned long NSUInteger;
12typedef int SInt32;
13typedef unsigned int UInt32;
14
15#else
16
17typedef int NSInteger;
18typedef unsigned int NSUInteger;
19typedef long SInt32;
20typedef unsigned long UInt32;
21#endif
22
Ted Kremenek6edb0292013-03-25 22:28:37 +000023typedef SInt32 OSStatus;
24
Stephen Hinesc568f1e2014-07-21 00:47:37 -070025typedef enum NSIntegerEnum : NSInteger {
26 EnumValueA,
27 EnumValueB
28} NSIntegerEnum;
29
Jordan Roseec087352012-09-05 22:56:26 +000030NSInteger getNSInteger();
31NSUInteger getNSUInteger();
32SInt32 getSInt32();
33UInt32 getUInt32();
Stephen Hinesc568f1e2014-07-21 00:47:37 -070034NSIntegerEnum getNSIntegerEnum();
Jordan Roseec087352012-09-05 22:56:26 +000035
36void testCorrectionInAllCases() {
37 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
38 printf("%s", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
39 printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
40 printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
41
Jordan Rosec8145bb2013-01-17 18:47:12 +000042 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
43 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +000044
Jordan Rosec8145bb2013-01-17 18:47:12 +000045 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
46 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +000047
Jordan Rosec8145bb2013-01-17 18:47:12 +000048 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
49 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +000050
Jordan Rosec8145bb2013-01-17 18:47:12 +000051 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
52 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
Stephen Hinesc568f1e2014-07-21 00:47:37 -070053
54 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}}
55
56 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
57 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +000058}
59
60@interface Foo {
61@public
62 NSInteger _value;
63}
64- (NSInteger)getInteger;
65
66@property NSInteger value;
67@end
68
69struct Bar {
70 NSInteger value;
71};
72
73
74void testParens(Foo *obj, struct Bar *record) {
75 NSInteger arr[4] = {0};
76 NSInteger i = 0;
77
Jordan Rose17ddc542012-12-05 18:44:44 +000078 // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr.
Jordan Roseec087352012-09-05 22:56:26 +000079 printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
80 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
81 printf("%s", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
82 printf("%s", obj->_value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
83 printf("%s", [obj getInteger]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
84 printf("%s", obj.value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
85 printf("%s", record->value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
86 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}}
87 printf("%s", *arr); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
88
89 // CHECK-NOT: fix-it:{{.*}}:")"
90
91 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}}
92
Jordan Rosec8145bb2013-01-17 18:47:12 +000093 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
94 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)("
95 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"
Jordan Roseec087352012-09-05 22:56:26 +000096}
97
98
99#if __LP64__
100
101void testWarn() {
102 printf("%d", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
103 printf("%u", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
104 printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
105 printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
106
Jordan Rosec8145bb2013-01-17 18:47:12 +0000107 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
108 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000109
Jordan Rosec8145bb2013-01-17 18:47:12 +0000110 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
111 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +0000112
Jordan Rosec8145bb2013-01-17 18:47:12 +0000113 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d"
114 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +0000115
Jordan Rosec8145bb2013-01-17 18:47:12 +0000116 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u"
117 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)"
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700118
119 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}}
120
121 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
122 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000123}
124
125void testPreserveHex() {
126 printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
127 printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
128
Jordan Rosec8145bb2013-01-17 18:47:12 +0000129 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx"
130 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000131
Jordan Rosec8145bb2013-01-17 18:47:12 +0000132 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%lx"
133 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +0000134}
135
Jordan Rose242ae3d2013-01-17 18:47:16 +0000136void testSignedness(NSInteger i, NSUInteger u) {
137 printf("%d", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
138 printf("%i", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
139 printf("%u", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
140
141 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
142 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
143 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld"
144}
145
Jordan Roseec087352012-09-05 22:56:26 +0000146void testNoWarn() {
147 printf("%ld", getNSInteger()); // no-warning
148 printf("%lu", getNSUInteger()); // no-warning
149 printf("%d", getSInt32()); // no-warning
150 printf("%u", getUInt32()); // no-warning
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700151 printf("%ld", getNSIntegerEnum()); // no-warning
Jordan Roseec087352012-09-05 22:56:26 +0000152}
153
154#else
155
156void testWarn() {
157 printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
158 printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
159 printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
160 printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
161
Jordan Rosec8145bb2013-01-17 18:47:12 +0000162 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(long)"
163 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)"
164 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)"
165 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)"
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700166
167 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}}
168
169 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000170}
171
172void testPreserveHex() {
173 printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
174 printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
175
Jordan Rosec8145bb2013-01-17 18:47:12 +0000176 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(long)"
177 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +0000178}
179
180void testNoWarn() {
181 printf("%d", getNSInteger()); // no-warning
182 printf("%u", getNSUInteger()); // no-warning
183 printf("%ld", getSInt32()); // no-warning
184 printf("%lu", getUInt32()); // no-warning
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700185 printf("%d", getNSIntegerEnum()); // no-warning
Jordan Roseec087352012-09-05 22:56:26 +0000186}
187
Jordan Rose242ae3d2013-01-17 18:47:16 +0000188void testSignedness(NSInteger i, NSUInteger u) {
189 // It is valid to use a specifier with the opposite signedness as long as
190 // the type is correct.
191 printf("%d", u); // no-warning
192 printf("%i", u); // no-warning
193 printf("%u", i); // no-warning
194}
195
Jordan Roseec087352012-09-05 22:56:26 +0000196#endif
197
198
199void testCasts() {
200 printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
201 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}}
202 printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
203 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}}
204
Jordan Rosec8145bb2013-01-17 18:47:12 +0000205 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
206 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000207
Jordan Rosec8145bb2013-01-17 18:47:12 +0000208 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
209 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +0000210
Jordan Rosec8145bb2013-01-17 18:47:12 +0000211 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
212 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +0000213
Jordan Rosec8145bb2013-01-17 18:47:12 +0000214 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
215 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700216
217 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}}
218
219 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
220 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:31}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000221}
Jordan Rose275b6f52012-09-13 02:11:03 +0000222
223void testCapitals() {
Jordan Rose670941c2012-09-13 02:11:15 +0000224 printf("%D", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}}
225 printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}}
226 printf("%O", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'o'?}}
Jordan Rose275b6f52012-09-13 02:11:03 +0000227
Jordan Rosec8145bb2013-01-17 18:47:12 +0000228 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"d"
229 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"u"
230 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"o"
Jordan Rose275b6f52012-09-13 02:11:03 +0000231
Jordan Rose670941c2012-09-13 02:11:15 +0000232
233 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'}}
234
235 // FIXME: offering two somewhat-conflicting fixits is less than ideal.
Jordan Rosec8145bb2013-01-17 18:47:12 +0000236 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
237 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
Jordan Rose275b6f52012-09-13 02:11:03 +0000238}
Ted Kremenek6edb0292013-03-25 22:28:37 +0000239
240void testLayeredTypedefs(OSStatus i) {
241 printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}}
Ted Kremenekb27564e2013-03-25 23:05:40 +0000242 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
Ted Kremenek6edb0292013-03-25 22:28:37 +0000243}
244