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