1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // This test checks for the various conversions and casting operations
4 // with address-space-qualified pointers.
5 
~AA6 struct A { virtual ~A() {} };
7 struct B : A { };
8 
9 typedef void *void_ptr;
10 typedef void __attribute__((address_space(1))) *void_ptr_1;
11 typedef void __attribute__((address_space(2))) *void_ptr_2;
12 
13 typedef int *int_ptr;
14 typedef int __attribute__((address_space(1))) *int_ptr_1;
15 typedef int __attribute__((address_space(2))) *int_ptr_2;
16 
17 typedef A *A_ptr;
18 typedef A __attribute__((address_space(1))) *A_ptr_1;
19 typedef A __attribute__((address_space(2))) *A_ptr_2;
20 
21 typedef B *B_ptr;
22 typedef B __attribute__((address_space(1))) *B_ptr_1;
23 typedef B __attribute__((address_space(2))) *B_ptr_2;
24 
test_const_cast(int_ptr ip,int_ptr_1 ip1,int_ptr_2 ip2,A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,const int * cip,const int * cip1)25 void test_const_cast(int_ptr ip, int_ptr_1 ip1, int_ptr_2 ip2,
26                      A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
27                      const int *cip,
28                      const int __attribute__((address_space(1))) *cip1) {
29   // Cannot use const_cast to cast between address spaces, add an
30   // address space, or remove an address space.
31   (void)const_cast<int_ptr>(ip1); // expected-error{{is not allowed}}
32   (void)const_cast<int_ptr>(ip2); // expected-error{{is not allowed}}
33   (void)const_cast<int_ptr_1>(ip); // expected-error{{is not allowed}}
34   (void)const_cast<int_ptr_1>(ip2); // expected-error{{is not allowed}}
35   (void)const_cast<int_ptr_2>(ip); // expected-error{{is not allowed}}
36   (void)const_cast<int_ptr_2>(ip1); // expected-error{{is not allowed}}
37 
38   (void)const_cast<A_ptr>(ap1); // expected-error{{is not allowed}}
39   (void)const_cast<A_ptr>(ap2); // expected-error{{is not allowed}}
40   (void)const_cast<A_ptr_1>(ap); // expected-error{{is not allowed}}
41   (void)const_cast<A_ptr_1>(ap2); // expected-error{{is not allowed}}
42   (void)const_cast<A_ptr_2>(ap); // expected-error{{is not allowed}}
43   (void)const_cast<A_ptr_2>(ap1); // expected-error{{is not allowed}}
44 
45   // It's acceptable to cast away constness.
46   (void)const_cast<int_ptr>(cip);
47   (void)const_cast<int_ptr_1>(cip1);
48 }
49 
test_static_cast(void_ptr vp,void_ptr_1 vp1,void_ptr_2 vp2,A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,B_ptr bp,B_ptr_1 bp1,B_ptr_2 bp2)50 void test_static_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
51                       A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
52                       B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
53   // Well-formed upcast
54   (void)static_cast<A_ptr>(bp);
55   (void)static_cast<A_ptr_1>(bp1);
56   (void)static_cast<A_ptr_2>(bp2);
57 
58   // Well-formed downcast
59   (void)static_cast<B_ptr>(ap);
60   (void)static_cast<B_ptr_1>(ap1);
61   (void)static_cast<B_ptr_2>(ap2);
62 
63   // Well-formed cast to/from void
64   (void)static_cast<void_ptr>(ap);
65   (void)static_cast<void_ptr_1>(ap1);
66   (void)static_cast<void_ptr_2>(ap2);
67   (void)static_cast<A_ptr>(vp);
68   (void)static_cast<A_ptr_1>(vp1);
69   (void)static_cast<A_ptr_2>(vp2);
70 
71   // Ill-formed upcasts
72   (void)static_cast<A_ptr>(bp1); // expected-error{{is not allowed}}
73   (void)static_cast<A_ptr>(bp2); // expected-error{{is not allowed}}
74   (void)static_cast<A_ptr_1>(bp); // expected-error{{is not allowed}}
75   (void)static_cast<A_ptr_1>(bp2); // expected-error{{is not allowed}}
76   (void)static_cast<A_ptr_2>(bp); // expected-error{{is not allowed}}
77   (void)static_cast<A_ptr_2>(bp1); // expected-error{{is not allowed}}
78 
79   // Ill-formed downcasts
80   (void)static_cast<B_ptr>(ap1); // expected-error{{casts away qualifiers}}
81   (void)static_cast<B_ptr>(ap2); // expected-error{{casts away qualifiers}}
82   (void)static_cast<B_ptr_1>(ap); // expected-error{{casts away qualifiers}}
83   (void)static_cast<B_ptr_1>(ap2); // expected-error{{casts away qualifiers}}
84   (void)static_cast<B_ptr_2>(ap); // expected-error{{casts away qualifiers}}
85   (void)static_cast<B_ptr_2>(ap1); // expected-error{{casts away qualifiers}}
86 
87   // Ill-formed cast to/from void
88   (void)static_cast<void_ptr>(ap1); // expected-error{{is not allowed}}
89   (void)static_cast<void_ptr>(ap2); // expected-error{{is not allowed}}
90   (void)static_cast<void_ptr_1>(ap); // expected-error{{is not allowed}}
91   (void)static_cast<void_ptr_1>(ap2); // expected-error{{is not allowed}}
92   (void)static_cast<void_ptr_2>(ap); // expected-error{{is not allowed}}
93   (void)static_cast<void_ptr_2>(ap1); // expected-error{{is not allowed}}
94   (void)static_cast<A_ptr>(vp1); // expected-error{{casts away qualifiers}}
95   (void)static_cast<A_ptr>(vp2); // expected-error{{casts away qualifiers}}
96   (void)static_cast<A_ptr_1>(vp); // expected-error{{casts away qualifiers}}
97   (void)static_cast<A_ptr_1>(vp2); // expected-error{{casts away qualifiers}}
98   (void)static_cast<A_ptr_2>(vp); // expected-error{{casts away qualifiers}}
99   (void)static_cast<A_ptr_2>(vp1); // expected-error{{casts away qualifiers}}
100 }
101 
test_dynamic_cast(A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,B_ptr bp,B_ptr_1 bp1,B_ptr_2 bp2)102 void test_dynamic_cast(A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
103                        B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
104   // Well-formed upcast
105   (void)dynamic_cast<A_ptr>(bp);
106   (void)dynamic_cast<A_ptr_1>(bp1);
107   (void)dynamic_cast<A_ptr_2>(bp2);
108 
109   // Well-formed downcast
110   (void)dynamic_cast<B_ptr>(ap);
111   (void)dynamic_cast<B_ptr_1>(ap1);
112   (void)dynamic_cast<B_ptr_2>(ap2);
113 
114   // Ill-formed upcasts
115   (void)dynamic_cast<A_ptr>(bp1); // expected-error{{casts away qualifiers}}
116   (void)dynamic_cast<A_ptr>(bp2); // expected-error{{casts away qualifiers}}
117   (void)dynamic_cast<A_ptr_1>(bp); // expected-error{{casts away qualifiers}}
118   (void)dynamic_cast<A_ptr_1>(bp2); // expected-error{{casts away qualifiers}}
119   (void)dynamic_cast<A_ptr_2>(bp); // expected-error{{casts away qualifiers}}
120   (void)dynamic_cast<A_ptr_2>(bp1); // expected-error{{casts away qualifiers}}
121 
122   // Ill-formed downcasts
123   (void)dynamic_cast<B_ptr>(ap1); // expected-error{{casts away qualifiers}}
124   (void)dynamic_cast<B_ptr>(ap2); // expected-error{{casts away qualifiers}}
125   (void)dynamic_cast<B_ptr_1>(ap); // expected-error{{casts away qualifiers}}
126   (void)dynamic_cast<B_ptr_1>(ap2); // expected-error{{casts away qualifiers}}
127   (void)dynamic_cast<B_ptr_2>(ap); // expected-error{{casts away qualifiers}}
128   (void)dynamic_cast<B_ptr_2>(ap1); // expected-error{{casts away qualifiers}}
129 }
130 
test_reinterpret_cast(void_ptr vp,void_ptr_1 vp1,void_ptr_2 vp2,A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,B_ptr bp,B_ptr_1 bp1,B_ptr_2 bp2,const void * cvp1)131 void test_reinterpret_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
132                            A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
133                            B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2,
134                            const void __attribute__((address_space(1))) *cvp1) {
135   // reinterpret_cast can be used to cast to a different address space.
136   (void)reinterpret_cast<A_ptr>(ap1);
137   (void)reinterpret_cast<A_ptr>(ap2);
138   (void)reinterpret_cast<A_ptr>(bp);
139   (void)reinterpret_cast<A_ptr>(bp1);
140   (void)reinterpret_cast<A_ptr>(bp2);
141   (void)reinterpret_cast<A_ptr>(vp);
142   (void)reinterpret_cast<A_ptr>(vp1);
143   (void)reinterpret_cast<A_ptr>(vp2);
144   (void)reinterpret_cast<A_ptr_1>(ap);
145   (void)reinterpret_cast<A_ptr_1>(ap2);
146   (void)reinterpret_cast<A_ptr_1>(bp);
147   (void)reinterpret_cast<A_ptr_1>(bp1);
148   (void)reinterpret_cast<A_ptr_1>(bp2);
149   (void)reinterpret_cast<A_ptr_1>(vp);
150   (void)reinterpret_cast<A_ptr_1>(vp1);
151   (void)reinterpret_cast<A_ptr_1>(vp2);
152 
153   // ... but don't try to cast away constness!
154   (void)reinterpret_cast<A_ptr_2>(cvp1); // expected-error{{casts away qualifiers}}
155 }
156 
test_cstyle_cast(void_ptr vp,void_ptr_1 vp1,void_ptr_2 vp2,A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,B_ptr bp,B_ptr_1 bp1,B_ptr_2 bp2,const void * cvp1)157 void test_cstyle_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
158                       A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
159                       B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2,
160                       const void __attribute__((address_space(1))) *cvp1) {
161   // C-style casts are the wild west of casts.
162   (void)(A_ptr)(ap1);
163   (void)(A_ptr)(ap2);
164   (void)(A_ptr)(bp);
165   (void)(A_ptr)(bp1);
166   (void)(A_ptr)(bp2);
167   (void)(A_ptr)(vp);
168   (void)(A_ptr)(vp1);
169   (void)(A_ptr)(vp2);
170   (void)(A_ptr_1)(ap);
171   (void)(A_ptr_1)(ap2);
172   (void)(A_ptr_1)(bp);
173   (void)(A_ptr_1)(bp1);
174   (void)(A_ptr_1)(bp2);
175   (void)(A_ptr_1)(vp);
176   (void)(A_ptr_1)(vp1);
177   (void)(A_ptr_1)(vp2);
178   (void)(A_ptr_2)(cvp1);
179 }
180 
test_implicit_conversion(void_ptr vp,void_ptr_1 vp1,void_ptr_2 vp2,A_ptr ap,A_ptr_1 ap1,A_ptr_2 ap2,B_ptr bp,B_ptr_1 bp1,B_ptr_2 bp2)181 void test_implicit_conversion(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
182                               A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
183                               B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
184   // Well-formed conversions
185   void_ptr vpA = ap;
186   void_ptr_1 vp_1A = ap1;
187   void_ptr_2 vp_2A = ap2;
188   A_ptr ap_A = bp;
189   A_ptr_1 ap_A1 = bp1;
190   A_ptr_2 ap_A2 = bp2;
191 
192   // Ill-formed conversions
193   void_ptr vpB = ap1; // expected-error{{cannot initialize a variable of type}}
194   void_ptr_1 vp_1B = ap2; // expected-error{{cannot initialize a variable of type}}
195   A_ptr ap_B = bp1; // expected-error{{cannot initialize a variable of type}}
196   A_ptr_1 ap_B1 = bp2; // expected-error{{cannot initialize a variable of type}}
197 }
198