1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -Wconversion -std=c++11 %s 2>&1 | FileCheck %s
3*67e74705SXin Li
4*67e74705SXin Li #include <stddef.h>
5*67e74705SXin Li
6*67e74705SXin Li typedef signed char int8_t;
7*67e74705SXin Li typedef signed short int16_t;
8*67e74705SXin Li typedef signed int int32_t;
9*67e74705SXin Li typedef signed long int64_t;
10*67e74705SXin Li
11*67e74705SXin Li typedef unsigned char uint8_t;
12*67e74705SXin Li typedef unsigned short uint16_t;
13*67e74705SXin Li typedef unsigned int uint32_t;
14*67e74705SXin Li typedef unsigned long uint64_t;
15*67e74705SXin Li
16*67e74705SXin Li // <rdar://problem/7909130>
17*67e74705SXin Li namespace test0 {
test1_positive(char * I,char * E)18*67e74705SXin Li int32_t test1_positive(char *I, char *E) {
19*67e74705SXin Li return (E - I); // expected-warning {{implicit conversion loses integer precision}}
20*67e74705SXin Li }
21*67e74705SXin Li
test1_negative(char * I,char * E)22*67e74705SXin Li int32_t test1_negative(char *I, char *E) {
23*67e74705SXin Li return static_cast<int32_t>(E - I);
24*67e74705SXin Li }
25*67e74705SXin Li
test2_positive(uint64_t x)26*67e74705SXin Li uint32_t test2_positive(uint64_t x) {
27*67e74705SXin Li return x; // expected-warning {{implicit conversion loses integer precision}}
28*67e74705SXin Li }
29*67e74705SXin Li
test2_negative(uint64_t x)30*67e74705SXin Li uint32_t test2_negative(uint64_t x) {
31*67e74705SXin Li return (uint32_t) x;
32*67e74705SXin Li }
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li namespace test1 {
test1(int x,unsigned y)36*67e74705SXin Li uint64_t test1(int x, unsigned y) {
37*67e74705SXin Li return sizeof(x == y);
38*67e74705SXin Li }
39*67e74705SXin Li
test2(int x,unsigned y)40*67e74705SXin Li uint64_t test2(int x, unsigned y) {
41*67e74705SXin Li return __alignof(x == y);
42*67e74705SXin Li }
43*67e74705SXin Li
44*67e74705SXin Li void * const foo();
test2(void * p)45*67e74705SXin Li bool test2(void *p) {
46*67e74705SXin Li return p == foo();
47*67e74705SXin Li }
48*67e74705SXin Li }
49*67e74705SXin Li
50*67e74705SXin Li namespace test2 {
51*67e74705SXin Li struct A {
52*67e74705SXin Li unsigned int x : 2;
Atest2::A53*67e74705SXin Li A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}}
54*67e74705SXin Li };
55*67e74705SXin Li }
56*67e74705SXin Li
57*67e74705SXin Li // This file tests -Wnull-conversion, a subcategory of -Wconversion
58*67e74705SXin Li // which is on by default.
59*67e74705SXin Li
test3()60*67e74705SXin Li void test3() {
61*67e74705SXin Li int a = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
62*67e74705SXin Li int b;
63*67e74705SXin Li b = NULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
64*67e74705SXin Li long l = NULL; // FIXME: this should also warn, but currently does not if sizeof(NULL)==sizeof(inttype)
65*67e74705SXin Li int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
66*67e74705SXin Li int d;
67*67e74705SXin Li d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
68*67e74705SXin Li bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}}
69*67e74705SXin Li char ch = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}}
70*67e74705SXin Li unsigned char uch = NULL; // expected-warning {{implicit conversion of NULL constant to 'unsigned char'}}
71*67e74705SXin Li short sh = NULL; // expected-warning {{implicit conversion of NULL constant to 'short'}}
72*67e74705SXin Li double dbl = NULL; // expected-warning {{implicit conversion of NULL constant to 'double'}}
73*67e74705SXin Li
74*67e74705SXin Li // Use FileCheck to ensure we don't get any unnecessary macro-expansion notes
75*67e74705SXin Li // (that don't appear as 'real' notes & can't be seen/tested by -verify)
76*67e74705SXin Li // CHECK-NOT: note:
77*67e74705SXin Li // CHECK: note: expanded from macro 'FINIT'
78*67e74705SXin Li #define FINIT int a3 = NULL;
79*67e74705SXin Li FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
80*67e74705SXin Li // we don't catch the case of #define FOO NULL ... int i = FOO; but that
81*67e74705SXin Li // seems a bit narrow anyway and avoiding that helps us skip other cases.
82*67e74705SXin Li
83*67e74705SXin Li int *ip = NULL;
84*67e74705SXin Li int (*fp)() = NULL;
85*67e74705SXin Li struct foo {
86*67e74705SXin Li int n;
87*67e74705SXin Li void func();
88*67e74705SXin Li };
89*67e74705SXin Li int foo::*datamem = NULL;
90*67e74705SXin Li int (foo::*funmem)() = NULL;
91*67e74705SXin Li }
92*67e74705SXin Li
93*67e74705SXin Li namespace test4 {
94*67e74705SXin Li // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once
95*67e74705SXin Li // not once for the template + once for every instantiation
96*67e74705SXin Li template<typename T>
tmpl(char c=NULL,T a=NULL,T b=1024)97*67e74705SXin Li void tmpl(char c = NULL, // expected-warning 3 {{implicit conversion of NULL constant to 'char'}}
98*67e74705SXin Li T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
99*67e74705SXin Li expected-warning {{implicit conversion of NULL constant to 'int'}}
100*67e74705SXin Li T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
101*67e74705SXin Li }
102*67e74705SXin Li
103*67e74705SXin Li template<typename T>
tmpl2(T t=NULL)104*67e74705SXin Li void tmpl2(T t = NULL) {
105*67e74705SXin Li }
106*67e74705SXin Li
func()107*67e74705SXin Li void func() {
108*67e74705SXin Li tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
109*67e74705SXin Li tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
110*67e74705SXin Li tmpl<int>();
111*67e74705SXin Li tmpl2<int*>();
112*67e74705SXin Li }
113*67e74705SXin Li }
114*67e74705SXin Li
115*67e74705SXin Li namespace test5 {
116*67e74705SXin Li template<int I>
func()117*67e74705SXin Li void func() {
118*67e74705SXin Li bool b = I;
119*67e74705SXin Li }
120*67e74705SXin Li
121*67e74705SXin Li template void func<3>();
122*67e74705SXin Li }
123*67e74705SXin Li
124*67e74705SXin Li namespace test6 {
func()125*67e74705SXin Li decltype(nullptr) func() {
126*67e74705SXin Li return NULL;
127*67e74705SXin Li }
128*67e74705SXin Li }
129*67e74705SXin Li
130*67e74705SXin Li namespace test7 {
fun()131*67e74705SXin Li bool fun() {
132*67e74705SXin Li bool x = nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
133*67e74705SXin Li if (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
134*67e74705SXin Li return nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
135*67e74705SXin Li }
136*67e74705SXin Li }
137*67e74705SXin Li
138*67e74705SXin Li namespace test8 {
139*67e74705SXin Li #define NULL_COND(cond) ((cond) ? &num : NULL)
140*67e74705SXin Li #define NULL_WRAPPER NULL_COND(false)
141*67e74705SXin Li
142*67e74705SXin Li // don't warn on NULL conversion through the conditional operator across a
143*67e74705SXin Li // macro boundary
macro()144*67e74705SXin Li void macro() {
145*67e74705SXin Li int num;
146*67e74705SXin Li bool b = NULL_COND(true);
147*67e74705SXin Li if (NULL_COND(true)) {}
148*67e74705SXin Li while (NULL_COND(true)) {}
149*67e74705SXin Li for (;NULL_COND(true);) {}
150*67e74705SXin Li do {} while (NULL_COND(true));
151*67e74705SXin Li
152*67e74705SXin Li if (NULL_WRAPPER) {}
153*67e74705SXin Li while (NULL_WRAPPER) {}
154*67e74705SXin Li for (;NULL_WRAPPER;) {}
155*67e74705SXin Li do {} while (NULL_WRAPPER);
156*67e74705SXin Li }
157*67e74705SXin Li
158*67e74705SXin Li // Identical to the previous function except with a template argument.
159*67e74705SXin Li // This ensures that template instantiation does not introduce any new
160*67e74705SXin Li // warnings.
161*67e74705SXin Li template <typename X>
template_and_macro()162*67e74705SXin Li void template_and_macro() {
163*67e74705SXin Li int num;
164*67e74705SXin Li bool b = NULL_COND(true);
165*67e74705SXin Li if (NULL_COND(true)) {}
166*67e74705SXin Li while (NULL_COND(true)) {}
167*67e74705SXin Li for (;NULL_COND(true);) {}
168*67e74705SXin Li do {} while (NULL_COND(true));
169*67e74705SXin Li
170*67e74705SXin Li if (NULL_WRAPPER) {}
171*67e74705SXin Li while (NULL_WRAPPER) {}
172*67e74705SXin Li for (;NULL_WRAPPER;) {}
173*67e74705SXin Li do {} while (NULL_WRAPPER);
174*67e74705SXin Li }
175*67e74705SXin Li
176*67e74705SXin Li // Identical to the previous function except the template argument affects
177*67e74705SXin Li // the conditional statement.
178*67e74705SXin Li template <typename X>
template_and_macro2()179*67e74705SXin Li void template_and_macro2() {
180*67e74705SXin Li X num;
181*67e74705SXin Li bool b = NULL_COND(true);
182*67e74705SXin Li if (NULL_COND(true)) {}
183*67e74705SXin Li while (NULL_COND(true)) {}
184*67e74705SXin Li for (;NULL_COND(true);) {}
185*67e74705SXin Li do {} while (NULL_COND(true));
186*67e74705SXin Li
187*67e74705SXin Li if (NULL_WRAPPER) {}
188*67e74705SXin Li while (NULL_WRAPPER) {}
189*67e74705SXin Li for (;NULL_WRAPPER;) {}
190*67e74705SXin Li do {} while (NULL_WRAPPER);
191*67e74705SXin Li }
192*67e74705SXin Li
run()193*67e74705SXin Li void run() {
194*67e74705SXin Li template_and_macro<int>();
195*67e74705SXin Li template_and_macro<double>();
196*67e74705SXin Li template_and_macro2<int>();
197*67e74705SXin Li template_and_macro2<double>();
198*67e74705SXin Li }
199*67e74705SXin Li }
200*67e74705SXin Li
201*67e74705SXin Li // Don't warn on a nullptr to bool conversion when the nullptr is the return
202*67e74705SXin Li // type of a function.
203*67e74705SXin Li namespace test9 {
204*67e74705SXin Li typedef decltype(nullptr) nullptr_t;
205*67e74705SXin Li nullptr_t EXIT();
206*67e74705SXin Li
test()207*67e74705SXin Li bool test() {
208*67e74705SXin Li return EXIT();
209*67e74705SXin Li }
210*67e74705SXin Li }
211*67e74705SXin Li
212*67e74705SXin Li // Test NULL macro inside a macro has same warnings nullptr inside a macro.
213*67e74705SXin Li namespace test10 {
214*67e74705SXin Li #define test1(cond) \
215*67e74705SXin Li ((cond) ? nullptr : NULL)
216*67e74705SXin Li #define test2(cond) \
217*67e74705SXin Li ((cond) ? NULL : nullptr)
218*67e74705SXin Li
219*67e74705SXin Li #define assert(cond) \
220*67e74705SXin Li ((cond) ? foo() : bar())
221*67e74705SXin Li void foo();
222*67e74705SXin Li void bar();
223*67e74705SXin Li
run(int x)224*67e74705SXin Li void run(int x) {
225*67e74705SXin Li if (test1(x)) {}
226*67e74705SXin Li if (test2(x)) {}
227*67e74705SXin Li assert(test1(x));
228*67e74705SXin Li assert(test2(x));
229*67e74705SXin Li }
230*67e74705SXin Li }
231*67e74705SXin Li
232*67e74705SXin Li namespace test11 {
233*67e74705SXin Li
234*67e74705SXin Li #define assert11(expr) ((expr) ? 0 : 0)
235*67e74705SXin Li
236*67e74705SXin Li // The whitespace in macro run1 are important to trigger the macro being split
237*67e74705SXin Li // over multiple SLocEntry's.
238*67e74705SXin Li #define run1() (dostuff() ? \
239*67e74705SXin Li NULL : NULL)
240*67e74705SXin Li #define run2() (dostuff() ? NULL : NULL)
241*67e74705SXin Li int dostuff ();
242*67e74705SXin Li
test(const char * content_type)243*67e74705SXin Li void test(const char * content_type) {
244*67e74705SXin Li assert11(run1());
245*67e74705SXin Li assert11(run2());
246*67e74705SXin Li }
247*67e74705SXin Li
248*67e74705SXin Li }
249*67e74705SXin Li
250*67e74705SXin Li namespace test12 {
251*67e74705SXin Li
252*67e74705SXin Li #define x return NULL;
253*67e74705SXin Li
run()254*67e74705SXin Li bool run() {
255*67e74705SXin Li x // expected-warning{{}}
256*67e74705SXin Li }
257*67e74705SXin Li
258*67e74705SXin Li }
259*67e74705SXin Li
260*67e74705SXin Li // More tests with macros. Specficially, test function-like macros that either
261*67e74705SXin Li // have a pointer return type or take pointer arguments. Basically, if the
262*67e74705SXin Li // macro was changed into a function and Clang doesn't warn, then it shouldn't
263*67e74705SXin Li // warn for the macro either.
264*67e74705SXin Li namespace test13 {
265*67e74705SXin Li #define check_str_nullptr_13(str) ((str) ? str : nullptr)
266*67e74705SXin Li #define check_str_null_13(str) ((str) ? str : NULL)
267*67e74705SXin Li #define test13(condition) if (condition) return;
268*67e74705SXin Li #define identity13(arg) arg
269*67e74705SXin Li #define CHECK13(condition) test13(identity13(!(condition)))
270*67e74705SXin Li
function1(const char * str)271*67e74705SXin Li void function1(const char* str) {
272*67e74705SXin Li CHECK13(check_str_nullptr_13(str));
273*67e74705SXin Li CHECK13(check_str_null_13(str));
274*67e74705SXin Li }
275*67e74705SXin Li
276*67e74705SXin Li bool some_bool_function(bool);
function2()277*67e74705SXin Li void function2() {
278*67e74705SXin Li CHECK13(some_bool_function(nullptr)); // expected-warning{{implicit conversion of nullptr constant to 'bool'}}
279*67e74705SXin Li CHECK13(some_bool_function(NULL)); // expected-warning{{implicit conversion of NULL constant to 'bool'}}
280*67e74705SXin Li }
281*67e74705SXin Li
282*67e74705SXin Li #define run_check_nullptr_13(str) \
283*67e74705SXin Li if (check_str_nullptr_13(str)) return;
284*67e74705SXin Li #define run_check_null_13(str) \
285*67e74705SXin Li if (check_str_null_13(str)) return;
function3(const char * str)286*67e74705SXin Li void function3(const char* str) {
287*67e74705SXin Li run_check_nullptr_13(str)
288*67e74705SXin Li run_check_null_13(str)
289*67e74705SXin Li if (check_str_nullptr_13(str)) return;
290*67e74705SXin Li if (check_str_null_13(str)) return;
291*67e74705SXin Li }
292*67e74705SXin Li
293*67e74705SXin Li void run(int* ptr);
294*67e74705SXin Li #define conditional_run_13(ptr) \
295*67e74705SXin Li if (ptr) run(ptr);
function4()296*67e74705SXin Li void function4() {
297*67e74705SXin Li conditional_run_13(nullptr);
298*67e74705SXin Li conditional_run_13(NULL);
299*67e74705SXin Li }
300*67e74705SXin Li }
301