blob: 06ec393552c0f80ccb99105816540e1252e6ceab [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
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
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
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
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
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
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
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
121void 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
130void 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
145void 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
154void 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
164void 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 Rose275b6f52012-09-13 02:11:03 +0000182
183void testCapitals() {
Jordan Rose670941c2012-09-13 02:11:15 +0000184 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 Rose275b6f52012-09-13 02:11:03 +0000187
Jordan Rose670941c2012-09-13 02:11:15 +0000188 // 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 Rose275b6f52012-09-13 02:11:03 +0000191
Jordan Rose670941c2012-09-13 02:11:15 +0000192
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 Rose275b6f52012-09-13 02:11:03 +0000198}