xref: /aosp_15_r20/external/clang/test/SemaCXX/cstyle-cast.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li // REQUIRES: LP64
3*67e74705SXin Li 
4*67e74705SXin Li struct A {};
5*67e74705SXin Li 
6*67e74705SXin Li // ----------- const_cast --------------
7*67e74705SXin Li 
8*67e74705SXin Li typedef char c;
9*67e74705SXin Li typedef c *cp;
10*67e74705SXin Li typedef cp *cpp;
11*67e74705SXin Li typedef cpp *cppp;
12*67e74705SXin Li typedef cppp &cpppr;
13*67e74705SXin Li typedef const cppp &cpppcr;
14*67e74705SXin Li typedef const char cc;
15*67e74705SXin Li typedef cc *ccp;
16*67e74705SXin Li typedef volatile ccp ccvp;
17*67e74705SXin Li typedef ccvp *ccvpp;
18*67e74705SXin Li typedef const volatile ccvpp ccvpcvp;
19*67e74705SXin Li typedef ccvpcvp *ccvpcvpp;
20*67e74705SXin Li typedef int iar[100];
21*67e74705SXin Li typedef iar &iarr;
22*67e74705SXin Li typedef int (*f)(int);
23*67e74705SXin Li 
t_cc()24*67e74705SXin Li void t_cc()
25*67e74705SXin Li {
26*67e74705SXin Li   ccvpcvpp var = 0;
27*67e74705SXin Li   // Cast away deep consts and volatiles.
28*67e74705SXin Li   char ***var2 = (cppp)(var);
29*67e74705SXin Li   char ***const &var3 = var2;
30*67e74705SXin Li   // Const reference to reference.
31*67e74705SXin Li   char ***&var4 = (cpppr)(var3);
32*67e74705SXin Li   // Drop reference. Intentionally without qualifier change.
33*67e74705SXin Li   char *** var5 = (cppp)(var4);
34*67e74705SXin Li   const int ar[100] = {0};
35*67e74705SXin Li   // Array decay. Intentionally without qualifier change.
36*67e74705SXin Li   int *pi = (int*)(ar);
37*67e74705SXin Li   f fp = 0;
38*67e74705SXin Li   // Don't misidentify fn** as a function pointer.
39*67e74705SXin Li   f *fpp = (f*)(&fp);
40*67e74705SXin Li   int const A::* const A::*icapcap = 0;
41*67e74705SXin Li   int A::* A::* iapap = (int A::* A::*)(icapcap);
42*67e74705SXin Li }
43*67e74705SXin Li 
44*67e74705SXin Li // ----------- static_cast -------------
45*67e74705SXin Li 
46*67e74705SXin Li struct B : public A {};             // Single public base.
47*67e74705SXin Li struct C1 : public virtual B {};    // Single virtual base.
48*67e74705SXin Li struct C2 : public virtual B {};
49*67e74705SXin Li struct D : public C1, public C2 {}; // Diamond
50*67e74705SXin Li struct E : private A {};            // Single private base.
51*67e74705SXin Li struct F : public C1 {};            // Single path to B with virtual.
52*67e74705SXin Li struct G1 : public B {};
53*67e74705SXin Li struct G2 : public B {};
54*67e74705SXin Li struct H : public G1, public G2 {}; // Ambiguous path to B.
55*67e74705SXin Li 
56*67e74705SXin Li enum Enum { En1, En2 };
57*67e74705SXin Li enum Onom { On1, On2 };
58*67e74705SXin Li 
59*67e74705SXin Li struct Co1 { operator int(); };
60*67e74705SXin Li struct Co2 { Co2(int); };
61*67e74705SXin Li struct Co3 { };
62*67e74705SXin Li struct Co4 { Co4(Co3); operator Co3(); };
63*67e74705SXin Li 
64*67e74705SXin Li // Explicit implicits
t_529_2()65*67e74705SXin Li void t_529_2()
66*67e74705SXin Li {
67*67e74705SXin Li   int i = 1;
68*67e74705SXin Li   (void)(float)(i);
69*67e74705SXin Li   double d = 1.0;
70*67e74705SXin Li   (void)(float)(d);
71*67e74705SXin Li   (void)(int)(d);
72*67e74705SXin Li   (void)(char)(i);
73*67e74705SXin Li   (void)(unsigned long)(i);
74*67e74705SXin Li   (void)(int)(En1);
75*67e74705SXin Li   (void)(double)(En1);
76*67e74705SXin Li   (void)(int&)(i);
77*67e74705SXin Li   (void)(const int&)(i);
78*67e74705SXin Li 
79*67e74705SXin Li   int ar[1];
80*67e74705SXin Li   (void)(const int*)(ar);
81*67e74705SXin Li   (void)(void (*)())(t_529_2);
82*67e74705SXin Li 
83*67e74705SXin Li   (void)(void*)(0);
84*67e74705SXin Li   (void)(void*)((int*)0);
85*67e74705SXin Li   (void)(volatile const void*)((const int*)0);
86*67e74705SXin Li   (void)(A*)((B*)0);
87*67e74705SXin Li   (void)(A&)(*((B*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}}
88*67e74705SXin Li   (void)(const B*)((C1*)0);
89*67e74705SXin Li   (void)(B&)(*((C1*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}}
90*67e74705SXin Li   (void)(A*)((D*)0);
91*67e74705SXin Li   (void)(const A&)(*((D*)0)); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}}
92*67e74705SXin Li   (void)(int B::*)((int A::*)0);
93*67e74705SXin Li   (void)(void (B::*)())((void (A::*)())0);
94*67e74705SXin Li   (void)(A*)((E*)0); // C-style cast ignores access control
95*67e74705SXin Li   (void)(void*)((const int*)0); // const_cast appended
96*67e74705SXin Li 
97*67e74705SXin Li   (void)(int)(Co1());
98*67e74705SXin Li   (void)(Co2)(1);
99*67e74705SXin Li   (void)(Co3)((Co4)(Co3()));
100*67e74705SXin Li 
101*67e74705SXin Li   // Bad code below
102*67e74705SXin Li   //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}}
103*67e74705SXin Li }
104*67e74705SXin Li 
105*67e74705SXin Li // Anything to void
t_529_4()106*67e74705SXin Li void t_529_4()
107*67e74705SXin Li {
108*67e74705SXin Li   (void)(1);
109*67e74705SXin Li   (void)(t_529_4);
110*67e74705SXin Li }
111*67e74705SXin Li 
112*67e74705SXin Li // Static downcasts
t_529_5_8()113*67e74705SXin Li void t_529_5_8()
114*67e74705SXin Li {
115*67e74705SXin Li   (void)(B*)((A*)0);
116*67e74705SXin Li   (void)(B&)(*((A*)0));
117*67e74705SXin Li   (void)(const G1*)((A*)0);
118*67e74705SXin Li   (void)(const G1&)(*((A*)0));
119*67e74705SXin Li   (void)(B*)((const A*)0); // const_cast appended
120*67e74705SXin Li   (void)(B&)(*((const A*)0)); // const_cast appended
121*67e74705SXin Li   (void)(E*)((A*)0); // access control ignored
122*67e74705SXin Li   (void)(E&)(*((A*)0)); // access control ignored
123*67e74705SXin Li 
124*67e74705SXin Li   // Bad code below
125*67e74705SXin Li 
126*67e74705SXin Li   (void)(C1*)((A*)0); // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
127*67e74705SXin Li   (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
128*67e74705SXin Li   (void)(D*)((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
129*67e74705SXin Li   (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
130*67e74705SXin Li   (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
131*67e74705SXin Li   (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
132*67e74705SXin Li 
133*67e74705SXin Li   // TODO: Test DR427. This requires user-defined conversions, though.
134*67e74705SXin Li }
135*67e74705SXin Li 
136*67e74705SXin Li // Enum conversions
t_529_7()137*67e74705SXin Li void t_529_7()
138*67e74705SXin Li {
139*67e74705SXin Li   (void)(Enum)(1);
140*67e74705SXin Li   (void)(Enum)(1.0);
141*67e74705SXin Li   (void)(Onom)(En1);
142*67e74705SXin Li 
143*67e74705SXin Li   // Bad code below
144*67e74705SXin Li 
145*67e74705SXin Li   (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'Enum' is not allowed}}
146*67e74705SXin Li }
147*67e74705SXin Li 
148*67e74705SXin Li // Void pointer to object pointer
t_529_10()149*67e74705SXin Li void t_529_10()
150*67e74705SXin Li {
151*67e74705SXin Li   (void)(int*)((void*)0);
152*67e74705SXin Li   (void)(const A*)((void*)0);
153*67e74705SXin Li   (void)(int*)((const void*)0); // const_cast appended
154*67e74705SXin Li }
155*67e74705SXin Li 
156*67e74705SXin Li // Member pointer upcast.
t_529_9()157*67e74705SXin Li void t_529_9()
158*67e74705SXin Li {
159*67e74705SXin Li   (void)(int A::*)((int B::*)0);
160*67e74705SXin Li 
161*67e74705SXin Li   // Bad code below
162*67e74705SXin Li   (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
163*67e74705SXin Li   (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
164*67e74705SXin Li }
165*67e74705SXin Li 
166*67e74705SXin Li // -------- reinterpret_cast -----------
167*67e74705SXin Li 
168*67e74705SXin Li enum test { testval = 1 };
169*67e74705SXin Li struct structure { int m; };
170*67e74705SXin Li typedef void (*fnptr)();
171*67e74705SXin Li 
172*67e74705SXin Li // Test conversion between pointer and integral types, as in p3 and p4.
integral_conversion()173*67e74705SXin Li void integral_conversion()
174*67e74705SXin Li {
175*67e74705SXin Li   void *vp = (void*)(testval);
176*67e74705SXin Li   long l = (long)(vp);
177*67e74705SXin Li   (void)(float*)(l);
178*67e74705SXin Li   fnptr fnp = (fnptr)(l);
179*67e74705SXin Li   (void)(char)(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
180*67e74705SXin Li   (void)(long)(fnp);
181*67e74705SXin Li }
182*67e74705SXin Li 
pointer_conversion()183*67e74705SXin Li void pointer_conversion()
184*67e74705SXin Li {
185*67e74705SXin Li   int *p1 = 0;
186*67e74705SXin Li   float *p2 = (float*)(p1);
187*67e74705SXin Li   structure *p3 = (structure*)(p2);
188*67e74705SXin Li   typedef int **ppint;
189*67e74705SXin Li   ppint *deep = (ppint*)(p3);
190*67e74705SXin Li   (void)(fnptr*)(deep);
191*67e74705SXin Li }
192*67e74705SXin Li 
constness()193*67e74705SXin Li void constness()
194*67e74705SXin Li {
195*67e74705SXin Li   int ***const ipppc = 0;
196*67e74705SXin Li   int const *icp = (int const*)(ipppc);
197*67e74705SXin Li   (void)(int*)(icp); // const_cast appended
198*67e74705SXin Li   int const *const **icpcpp = (int const* const**)(ipppc); // const_cast appended
199*67e74705SXin Li   int *ip = (int*)(icpcpp);
200*67e74705SXin Li   (void)(int const*)(ip);
201*67e74705SXin Li   (void)(int const* const* const*)(ipppc);
202*67e74705SXin Li }
203*67e74705SXin Li 
fnptrs()204*67e74705SXin Li void fnptrs()
205*67e74705SXin Li {
206*67e74705SXin Li   typedef int (*fnptr2)(int);
207*67e74705SXin Li   fnptr fp = 0;
208*67e74705SXin Li   (void)(fnptr2)(fp);
209*67e74705SXin Li   void *vp = (void*)(fp);
210*67e74705SXin Li   (void)(fnptr)(vp);
211*67e74705SXin Li }
212*67e74705SXin Li 
refs()213*67e74705SXin Li void refs()
214*67e74705SXin Li {
215*67e74705SXin Li   long l = 0;
216*67e74705SXin Li   char &c = (char&)(l);
217*67e74705SXin Li   // Bad: from rvalue
218*67e74705SXin Li   (void)(int&)(&c); // expected-error {{C-style cast from rvalue to reference type 'int &'}}
219*67e74705SXin Li }
220*67e74705SXin Li 
memptrs()221*67e74705SXin Li void memptrs()
222*67e74705SXin Li {
223*67e74705SXin Li   const int structure::*psi = 0;
224*67e74705SXin Li   (void)(const float structure::*)(psi);
225*67e74705SXin Li   (void)(int structure::*)(psi); // const_cast appended
226*67e74705SXin Li 
227*67e74705SXin Li   void (structure::*psf)() = 0;
228*67e74705SXin Li   (void)(int (structure::*)())(psf);
229*67e74705SXin Li 
230*67e74705SXin Li   (void)(void (structure::*)())(psi); // expected-error-re {{C-style cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
231*67e74705SXin Li   (void)(int structure::*)(psf); // expected-error-re {{C-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
232*67e74705SXin Li }
233