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