blob: f5205643489a0e39e971568e91d23c30ed7f352f [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 Rose4c266aa2012-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 Roseaee34382012-09-05 22:56:26 +00006
Jordan Rose4c266aa2012-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 Roseaee34382012-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
Ted Kremenekcd3d4402013-03-25 22:28:37 +000026typedef SInt32 OSStatus;
27
Jordan Roseaee34382012-09-05 22:56:26 +000028NSInteger getNSInteger();
29NSUInteger getNSUInteger();
30SInt32 getSInt32();
31UInt32 getUInt32();
32
33void testCorrectionInAllCases() {
34 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
35 printf("%s", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
36 printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
37 printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
38
Jordan Roseb169ccc2013-01-17 18:47:12 +000039 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
40 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +000041
Jordan Roseb169ccc2013-01-17 18:47:12 +000042 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
43 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +000044
Jordan Roseb169ccc2013-01-17 18:47:12 +000045 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
46 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +000047
Jordan Roseb169ccc2013-01-17 18:47:12 +000048 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
49 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
Jordan Roseaee34382012-09-05 22:56:26 +000050}
51
52@interface Foo {
53@public
54 NSInteger _value;
55}
56- (NSInteger)getInteger;
57
58@property NSInteger value;
59@end
60
61struct Bar {
62 NSInteger value;
63};
64
65
66void testParens(Foo *obj, struct Bar *record) {
67 NSInteger arr[4] = {0};
68 NSInteger i = 0;
69
Jordan Roseea0fdfe2012-12-05 18:44:44 +000070 // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr.
Jordan Roseaee34382012-09-05 22:56:26 +000071 printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
72 printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
73 printf("%s", i); // 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", [obj getInteger]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
76 printf("%s", obj.value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
77 printf("%s", record->value); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
78 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}}
79 printf("%s", *arr); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
80
81 // CHECK-NOT: fix-it:{{.*}}:")"
82
83 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}}
84
Jordan Roseb169ccc2013-01-17 18:47:12 +000085 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
86 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)("
87 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:25}:")"
Jordan Roseaee34382012-09-05 22:56:26 +000088}
89
90
91#if __LP64__
92
93void testWarn() {
94 printf("%d", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
95 printf("%u", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
96 printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
97 printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
98
Jordan Roseb169ccc2013-01-17 18:47:12 +000099 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
100 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000101
Jordan Roseb169ccc2013-01-17 18:47:12 +0000102 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
103 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000104
Jordan Roseb169ccc2013-01-17 18:47:12 +0000105 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d"
106 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000107
Jordan Roseb169ccc2013-01-17 18:47:12 +0000108 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u"
109 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000110}
111
112void testPreserveHex() {
113 printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
114 printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
115
Jordan Roseb169ccc2013-01-17 18:47:12 +0000116 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx"
117 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000118
Jordan Roseb169ccc2013-01-17 18:47:12 +0000119 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%lx"
120 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000121}
122
Jordan Roseaa7a3b32013-01-17 18:47:16 +0000123void testSignedness(NSInteger i, NSUInteger u) {
124 printf("%d", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
125 printf("%i", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
126 printf("%u", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
127
128 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
129 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu"
130 // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld"
131}
132
Jordan Roseaee34382012-09-05 22:56:26 +0000133void testNoWarn() {
134 printf("%ld", getNSInteger()); // no-warning
135 printf("%lu", getNSUInteger()); // no-warning
136 printf("%d", getSInt32()); // no-warning
137 printf("%u", getUInt32()); // no-warning
138}
139
140#else
141
142void testWarn() {
143 printf("%ld", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
144 printf("%lu", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
145 printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
146 printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}}
147
Jordan Roseb169ccc2013-01-17 18:47:12 +0000148 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(long)"
149 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)"
150 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)"
151 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000152}
153
154void testPreserveHex() {
155 printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
156 printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}}
157
Jordan Roseb169ccc2013-01-17 18:47:12 +0000158 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(long)"
159 // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000160}
161
162void testNoWarn() {
163 printf("%d", getNSInteger()); // no-warning
164 printf("%u", getNSUInteger()); // no-warning
165 printf("%ld", getSInt32()); // no-warning
166 printf("%lu", getUInt32()); // no-warning
167}
168
Jordan Roseaa7a3b32013-01-17 18:47:16 +0000169void testSignedness(NSInteger i, NSUInteger u) {
170 // It is valid to use a specifier with the opposite signedness as long as
171 // the type is correct.
172 printf("%d", u); // no-warning
173 printf("%i", u); // no-warning
174 printf("%u", i); // no-warning
175}
176
Jordan Roseaee34382012-09-05 22:56:26 +0000177#endif
178
179
180void testCasts() {
181 printf("%s", (NSInteger)0); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
182 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}}
183 printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}}
184 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}}
185
Jordan Roseb169ccc2013-01-17 18:47:12 +0000186 // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld"
187 // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000188
Jordan Roseb169ccc2013-01-17 18:47:12 +0000189 // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu"
190 // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)"
Jordan Roseaee34382012-09-05 22:56:26 +0000191
Jordan Roseb169ccc2013-01-17 18:47:12 +0000192 // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d"
193 // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000194
Jordan Roseb169ccc2013-01-17 18:47:12 +0000195 // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
196 // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
Jordan Roseaee34382012-09-05 22:56:26 +0000197}
Jordan Rose510260c2012-09-13 02:11:03 +0000198
199void testCapitals() {
Jordan Rose4c266aa2012-09-13 02:11:15 +0000200 printf("%D", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}}
201 printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}}
202 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 +0000203
Jordan Roseb169ccc2013-01-17 18:47:12 +0000204 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"d"
205 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"u"
206 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"o"
Jordan Rose510260c2012-09-13 02:11:03 +0000207
Jordan Rose4c266aa2012-09-13 02:11:15 +0000208
209 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'}}
210
211 // FIXME: offering two somewhat-conflicting fixits is less than ideal.
Jordan Roseb169ccc2013-01-17 18:47:12 +0000212 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d"
213 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D"
Jordan Rose510260c2012-09-13 02:11:03 +0000214}
Ted Kremenekcd3d4402013-03-25 22:28:37 +0000215
216void testLayeredTypedefs(OSStatus i) {
217 printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}}
Ted Kremenek30b77bf2013-03-25 23:05:40 +0000218 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
Ted Kremenekcd3d4402013-03-25 22:28:37 +0000219}
220