blob: cfaac29e904b12b38c8628c130477ab94258dd87 [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
Jordan Rose670941c2012-09-13 02:11:15 +00004// 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 Roseec087352012-09-05 22:56:26 +00006
Jordan Rose670941c2012-09-13 02:11:15 +00007// 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 Roseec087352012-09-05 22:56:26 +00009
10int printf(const char * restrict, ...);
11
12#if __LP64__
13typedef long NSInteger;
14typedef unsigned long NSUInteger;
15typedef int SInt32;
16typedef unsigned int UInt32;
17
18#else
19
20typedef int NSInteger;
21typedef unsigned int NSUInteger;
22typedef long SInt32;
23typedef unsigned long UInt32;
24#endif
25
26NSInteger getNSInteger();
27NSUInteger getNSUInteger();
28SInt32 getSInt32();
29UInt32 getUInt32();
30
31void 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 Rosec8145bb2013-01-17 18:47:12 +000037 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
38 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +000039
Jordan Rosec8145bb2013-01-17 18:47:12 +000040 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
41 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +000042
Jordan Rosec8145bb2013-01-17 18:47:12 +000043 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
44 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +000045
Jordan Rosec8145bb2013-01-17 18:47:12 +000046 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
47 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
Jordan Roseec087352012-09-05 22:56:26 +000048}
49
50@interface Foo {
51@public
52 NSInteger _value;
53}
54- (NSInteger)getInteger;
55
56@property NSInteger value;
57@end
58
59struct Bar {
60 NSInteger value;
61};
62
63
64void testParens(Foo *obj, struct Bar *record) {
65 NSInteger arr[4] = {0};
66 NSInteger i = 0;
67
Jordan Rose17ddc542012-12-05 18:44:44 +000068 // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr.
Jordan Roseec087352012-09-05 22:56:26 +000069 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 Rosec8145bb2013-01-17 18:47:12 +000083 // 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 Roseec087352012-09-05 22:56:26 +000086}
87
88
89#if __LP64__
90
91void 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 Rosec8145bb2013-01-17 18:47:12 +000097 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
98 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +000099
Jordan Rosec8145bb2013-01-17 18:47:12 +0000100 // 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 Roseec087352012-09-05 22:56:26 +0000102
Jordan Rosec8145bb2013-01-17 18:47:12 +0000103 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d"
104 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +0000105
Jordan Rosec8145bb2013-01-17 18:47:12 +0000106 // 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 Roseec087352012-09-05 22:56:26 +0000108}
109
110void 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 Rosec8145bb2013-01-17 18:47:12 +0000114 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx"
115 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000116
Jordan Rosec8145bb2013-01-17 18:47:12 +0000117 // 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 Roseec087352012-09-05 22:56:26 +0000119}
120
Jordan Rose242ae3d2013-01-17 18:47:16 +0000121void 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 Roseec087352012-09-05 22:56:26 +0000131void 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
140void 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 Rosec8145bb2013-01-17 18:47:12 +0000146 // 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 Roseec087352012-09-05 22:56:26 +0000150}
151
152void 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 Rosec8145bb2013-01-17 18:47:12 +0000156 // 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 Roseec087352012-09-05 22:56:26 +0000158}
159
160void 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 Rose242ae3d2013-01-17 18:47:16 +0000167void 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 Roseec087352012-09-05 22:56:26 +0000175#endif
176
177
178void 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 Rosec8145bb2013-01-17 18:47:12 +0000184 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
185 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)"
Jordan Roseec087352012-09-05 22:56:26 +0000186
Jordan Rosec8145bb2013-01-17 18:47:12 +0000187 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
188 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)"
Jordan Roseec087352012-09-05 22:56:26 +0000189
Jordan Rosec8145bb2013-01-17 18:47:12 +0000190 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
191 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)"
Jordan Roseec087352012-09-05 22:56:26 +0000192
Jordan Rosec8145bb2013-01-17 18:47:12 +0000193 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
194 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
Jordan Roseec087352012-09-05 22:56:26 +0000195}
Jordan Rose275b6f52012-09-13 02:11:03 +0000196
197void testCapitals() {
Jordan Rose670941c2012-09-13 02:11:15 +0000198 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 Rose275b6f52012-09-13 02:11:03 +0000201
Jordan Rosec8145bb2013-01-17 18:47:12 +0000202 // 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 Rose275b6f52012-09-13 02:11:03 +0000205
Jordan Rose670941c2012-09-13 02:11:15 +0000206
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 Rosec8145bb2013-01-17 18:47:12 +0000210 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
211 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
Jordan Rose275b6f52012-09-13 02:11:03 +0000212}