xref: /aosp_15_r20/external/clang/test/SemaCXX/conversion.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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