1 | // RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s |
2 | // rdar://8843600 |
3 | |
4 | void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to '__strong id'}} |
5 | { |
6 | void* voidp_val; |
7 | (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}} |
8 | (void)(id)arg; |
9 | (void)(__autoreleasing id*)arg; // expected-error{{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}} |
10 | (void)(id*)arg; // expected-error{{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}} |
11 | |
12 | (void)(__autoreleasing id**)voidp_val; |
13 | (void)(void*)voidp_val; |
14 | (void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed}} |
15 | cvt((void*)arg); // expected-error {{no matching function for call to 'cvt'}} |
16 | cvt(0); |
17 | (void)(__strong id**)(0); |
18 | |
19 | // FIXME: Diagnostic could be better here. |
20 | return arg; // expected-error{{cannot initialize return object of type 'void *' with an lvalue of type '__strong id'}} |
21 | } |
22 | |
23 | // rdar://8898937 |
24 | namespace rdar8898937 { |
25 | |
26 | typedef void (^dispatch_block_t)(void); |
27 | |
28 | void dispatch_once(dispatch_block_t block); |
29 | static void _dispatch_once(dispatch_block_t block) |
30 | { |
31 | dispatch_once(block); |
32 | } |
33 | |
34 | } |
35 | |
36 | void static_casts(id arg) { |
37 | void* voidp_val; |
38 | (void)static_cast<int*>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'int *'}} |
39 | (void)static_cast<id>(arg); |
40 | (void)static_cast<__autoreleasing id*>(arg); // expected-error{{cannot cast from type 'id' to pointer type '__autoreleasing id *'}} |
41 | (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__strong id *'}} |
42 | |
43 | (void)static_cast<__autoreleasing id**>(voidp_val); |
44 | (void)static_cast<void*>(voidp_val); |
45 | (void)static_cast<void**>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'void **'}} |
46 | (void)static_cast<__strong id**>(0); |
47 | |
48 | __strong id *idp; |
49 | (void)static_cast<__autoreleasing id*>(idp); // expected-error{{static_cast from '__strong id *' to '__autoreleasing id *' is not allowed}} |
50 | (void)static_cast<__weak id*>(idp); // expected-error{{static_cast from '__strong id *' to '__weak id *' is not allowed}} |
51 | } |
52 | |
53 | void test_const_cast(__strong id *sip, __weak id *wip, |
54 | const __strong id *csip, __weak const id *cwip) { |
55 | // Cannot use const_cast to cast between ownership qualifications or |
56 | // add/remove ownership qualifications. |
57 | (void)const_cast<__strong id *>(wip); // expected-error{{is not allowed}} |
58 | (void)const_cast<__weak id *>(sip); // expected-error{{is not allowed}} |
59 | |
60 | // It's acceptable to cast away constness. |
61 | (void)const_cast<__strong id *>(csip); |
62 | (void)const_cast<__weak id *>(cwip); |
63 | } |
64 | |
65 | void test_reinterpret_cast(__strong id *sip, __weak id *wip, |
66 | const __strong id *csip, __weak const id *cwip) { |
67 | // Okay to reinterpret_cast to add/remove/change ownership |
68 | // qualifications. |
69 | (void)reinterpret_cast<__strong id *>(wip); |
70 | (void)reinterpret_cast<__weak id *>(sip); |
71 | |
72 | // Not allowed to cast away constness |
73 | (void)reinterpret_cast<__strong id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__strong id *' casts away qualifiers}} |
74 | (void)reinterpret_cast<__weak id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__weak id *' casts away qualifiers}} |
75 | (void)reinterpret_cast<__weak id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__weak id *' casts away qualifiers}} |
76 | (void)reinterpret_cast<__strong id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__strong id *' casts away qualifiers}} |
77 | } |
78 | |
79 | void test_cstyle_cast(__strong id *sip, __weak id *wip, |
80 | const __strong id *csip, __weak const id *cwip) { |
81 | // C-style casts aren't allowed to change Objective-C ownership |
82 | // qualifiers (beyond what the normal implicit conversion allows). |
83 | |
84 | (void)(__strong id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id *' casts away qualifiers}} |
85 | (void)(__strong id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id *' casts away qualifiers}} |
86 | (void)(__weak id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id *' casts away qualifiers}} |
87 | (void)(__weak id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id *' casts away qualifiers}} |
88 | |
89 | (void)(__strong const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id const *' casts away qualifiers}} |
90 | (void)(__strong const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id const *' casts away qualifiers}} |
91 | (void)(__weak const id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id const *' casts away qualifiers}} |
92 | (void)(__weak const id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id const *' casts away qualifiers}} |
93 | (void)(__autoreleasing const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__autoreleasing id const *' casts away qualifiers}} |
94 | (void)(__autoreleasing const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__autoreleasing id const *' casts away qualifiers}} |
95 | (void)(__autoreleasing const id *)sip; |
96 | (void)(__autoreleasing const id *)csip; |
97 | } |
98 | |
99 | void test_functional_cast(__strong id *sip, __weak id *wip, |
100 | __autoreleasing id *aip) { |
101 | // Functional casts aren't allowed to change Objective-C ownership |
102 | // qualifiers (beyond what the normal implicit conversion allows). |
103 | |
104 | typedef __strong id *strong_id_pointer; |
105 | typedef __weak id *weak_id_pointer; |
106 | typedef __autoreleasing id *autoreleasing_id_pointer; |
107 | |
108 | typedef const __strong id *const_strong_id_pointer; |
109 | typedef const __weak id *const_weak_id_pointer; |
110 | typedef const __autoreleasing id *const_autoreleasing_id_pointer; |
111 | |
112 | (void)strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'strong_id_pointer' (aka '__strong id *') casts away qualifiers}} |
113 | (void)weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'weak_id_pointer' (aka '__weak id *') casts away qualifiers}} |
114 | (void)autoreleasing_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} |
115 | (void)autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} |
116 | (void)const_strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'const_strong_id_pointer' (aka 'const __strong id *') casts away qualifiers}} |
117 | (void)const_weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'const_weak_id_pointer' (aka 'const __weak id *') casts away qualifiers}} |
118 | (void)const_autoreleasing_id_pointer(sip); |
119 | (void)const_autoreleasing_id_pointer(aip); |
120 | (void)const_autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'const_autoreleasing_id_pointer' (aka 'const __autoreleasing id *') casts away qualifiers}} |
121 | } |
122 | |
123 | void test_unsafe_unretained(__strong id *sip, __weak id *wip, |
124 | __autoreleasing id *aip, |
125 | __unsafe_unretained id *uip, |
126 | const __unsafe_unretained id *cuip) { |
127 | uip = sip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__strong id *'}} |
128 | uip = wip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__weak id *'}} |
129 | uip = aip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__autoreleasing id *'}} |
130 | |
131 | cuip = sip; |
132 | cuip = wip; // expected-error{{assigning to '__unsafe_unretained id const *' from incompatible type '__weak id *'}} |
133 | cuip = aip; |
134 | } |
135 | |
136 | void to_void(__strong id *sip, __weak id *wip, |
137 | __autoreleasing id *aip, |
138 | __unsafe_unretained id *uip) { |
139 | void *vp1 = sip; |
140 | void *vp2 = wip; |
141 | void *vp3 = aip; |
142 | void *vp4 = uip; |
143 | (void)(void*)sip; |
144 | (void)(void*)wip; |
145 | (void)(void*)aip; |
146 | (void)(void*)uip; |
147 | (void)static_cast<void*>(sip); |
148 | (void)static_cast<void*>(wip); |
149 | (void)static_cast<void*>(aip); |
150 | (void)static_cast<void*>(uip); |
151 | (void)reinterpret_cast<void*>(sip); |
152 | (void)reinterpret_cast<void*>(wip); |
153 | (void)reinterpret_cast<void*>(aip); |
154 | (void)reinterpret_cast<void*>(uip); |
155 | |
156 | (void)(void*)&sip; |
157 | (void)(void*)&wip; |
158 | (void)(void*)&aip; |
159 | (void)(void*)&uip; |
160 | (void)static_cast<void*>(&sip); |
161 | (void)static_cast<void*>(&wip); |
162 | (void)static_cast<void*>(&aip); |
163 | (void)static_cast<void*>(&uip); |
164 | (void)reinterpret_cast<void*>(&sip); |
165 | (void)reinterpret_cast<void*>(&wip); |
166 | (void)reinterpret_cast<void*>(&aip); |
167 | (void)reinterpret_cast<void*>(&uip); |
168 | } |
169 | |
170 | void from_void(void *vp) { |
171 | __strong id *sip = (__strong id *)vp; |
172 | __weak id *wip = (__weak id *)vp; |
173 | __autoreleasing id *aip = (__autoreleasing id *)vp; |
174 | __unsafe_unretained id *uip = (__unsafe_unretained id *)vp; |
175 | __strong id *sip2 = static_cast<__strong id *>(vp); |
176 | __weak id *wip2 = static_cast<__weak id *>(vp); |
177 | __autoreleasing id *aip2 = static_cast<__autoreleasing id *>(vp); |
178 | __unsafe_unretained id *uip2 = static_cast<__unsafe_unretained id *>(vp); |
179 | __strong id *sip3 = reinterpret_cast<__strong id *>(vp); |
180 | __weak id *wip3 = reinterpret_cast<__weak id *>(vp); |
181 | __autoreleasing id *aip3 = reinterpret_cast<__autoreleasing id *>(vp); |
182 | __unsafe_unretained id *uip3 = reinterpret_cast<__unsafe_unretained id *>(vp); |
183 | |
184 | __strong id **sipp = (__strong id **)vp; |
185 | __weak id **wipp = (__weak id **)vp; |
186 | __autoreleasing id **aipp = (__autoreleasing id **)vp; |
187 | __unsafe_unretained id **uipp = (__unsafe_unretained id **)vp; |
188 | |
189 | sip = vp; // expected-error{{assigning to '__strong id *' from incompatible type 'void *'}} |
190 | wip = vp; // expected-error{{assigning to '__weak id *' from incompatible type 'void *'}} |
191 | aip = vp; // expected-error{{assigning to '__autoreleasing id *' from incompatible type 'void *'}} |
192 | uip = vp; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type 'void *'}} |
193 | } |
194 | |
195 | typedef void (^Block)(); |
196 | typedef void (^Block_strong)() __strong; |
197 | typedef void (^Block_autoreleasing)() __autoreleasing; |
198 | |
199 | @class NSString; |
200 | |
201 | void ownership_transfer_in_cast(void *vp, Block *pblk) { |
202 | __strong NSString **sip2 = static_cast<NSString **>(static_cast<__strong id *>(vp)); |
203 | __strong NSString **&si2pref = static_cast<NSString **&>(sip2); |
204 | __weak NSString **wip2 = static_cast<NSString **>(static_cast<__weak id *>(vp)); |
205 | __autoreleasing id *aip2 = static_cast<id *>(static_cast<__autoreleasing id *>(vp)); |
206 | __unsafe_unretained id *uip2 = static_cast<id *>(static_cast<__unsafe_unretained id *>(vp)); |
207 | __strong id *sip3 = reinterpret_cast<id *>(reinterpret_cast<__strong id *>(vp)); |
208 | __weak id *wip3 = reinterpret_cast<id *>(reinterpret_cast<__weak id *>(vp)); |
209 | __autoreleasing id *aip3 = reinterpret_cast<id *>(reinterpret_cast<__autoreleasing id *>(vp)); |
210 | __unsafe_unretained id *uip3 = reinterpret_cast<id *>(reinterpret_cast<__unsafe_unretained id *>(vp)); |
211 | |
212 | Block_strong blk_strong1; |
213 | Block_strong blk_strong2 = static_cast<Block>(blk_strong1); |
214 | Block_autoreleasing *blk_auto = static_cast<Block*>(pblk); |
215 | } |
216 | |
217 | // Make sure we don't crash. |
218 | void writeback_test(NSString & &) {} // expected-error {{type name declared as a reference to a reference}} |
219 | |