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 | |
6 | 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 | |
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 | |
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 | |
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 | |
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't be used to cast to a different address space unless they are matching (i.e. overlapping). |
136 | (void)reinterpret_cast<A_ptr>(ap1); // expected-error{{reinterpret_cast from 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') to 'A_ptr' (aka 'A *') is not allowed}} |
137 | (void)reinterpret_cast<A_ptr>(ap2); // expected-error{{reinterpret_cast from 'A_ptr_2' (aka '__attribute__((address_space(2))) A *') to 'A_ptr' (aka 'A *') is not allowed}} |
138 | (void)reinterpret_cast<A_ptr>(bp); |
139 | (void)reinterpret_cast<A_ptr>(bp1); // expected-error{{reinterpret_cast from 'B_ptr_1' (aka '__attribute__((address_space(1))) B *') to 'A_ptr' (aka 'A *') is not allowed}} |
140 | (void)reinterpret_cast<A_ptr>(bp2); // expected-error{{reinterpret_cast from 'B_ptr_2' (aka '__attribute__((address_space(2))) B *') to 'A_ptr' (aka 'A *') is not allowed}} |
141 | (void)reinterpret_cast<A_ptr>(vp); |
142 | (void)reinterpret_cast<A_ptr>(vp1); // expected-error{{reinterpret_cast from 'void_ptr_1' (aka '__attribute__((address_space(1))) void *') to 'A_ptr' (aka 'A *') is not allowed}} |
143 | (void)reinterpret_cast<A_ptr>(vp2); // expected-error{{reinterpret_cast from 'void_ptr_2' (aka '__attribute__((address_space(2))) void *') to 'A_ptr' (aka 'A *') is not allowed}} |
144 | (void)reinterpret_cast<A_ptr_1>(ap); // expected-error{{reinterpret_cast from 'A_ptr' (aka 'A *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
145 | (void)reinterpret_cast<A_ptr_1>(ap2); // expected-error{{reinterpret_cast from 'A_ptr_2' (aka '__attribute__((address_space(2))) A *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
146 | (void)reinterpret_cast<A_ptr_1>(bp); // expected-error{{reinterpret_cast from 'B_ptr' (aka 'B *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
147 | (void)reinterpret_cast<A_ptr_1>(bp1); |
148 | (void)reinterpret_cast<A_ptr_1>(bp2); // expected-error{{reinterpret_cast from 'B_ptr_2' (aka '__attribute__((address_space(2))) B *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
149 | (void)reinterpret_cast<A_ptr_1>(vp); // expected-error{{reinterpret_cast from 'void_ptr' (aka 'void *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
150 | (void)reinterpret_cast<A_ptr_1>(vp1); |
151 | (void)reinterpret_cast<A_ptr_1>(vp2); // expected-error{{reinterpret_cast from 'void_ptr_2' (aka '__attribute__((address_space(2))) void *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}} |
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 | |
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 | |
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 | |