arc-type-conversion.mm revision 0a85183be6930571f3af8e5a976d24c3f95e5b25
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{{C-style cast from 'id' to '__strong id *' casts away qualifiers}} 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 {{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 *'}} 44 (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__strong id *'}} 45 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) { 58 // Cannot use const_cast to cast between ownership qualifications or 59 // add/remove ownership qualifications. 60 (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) { 70 // Okay to reinterpret_cast to add/remove/change ownership 71 // 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) { 84 // C-style casts aren't allowed to change Objective-C ownership 85 // 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) { 104 // Functional casts aren't allowed to change Objective-C ownership 105 // 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} 197 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)); 206 __weak NSString **wip2 = static_cast<NSString **>(static_cast<__weak id *>(vp)); 207 __autoreleasing id *aip2 = static_cast<id *>(static_cast<__autoreleasing id *>(vp)); 208 __unsafe_unretained id *uip2 = static_cast<id *>(static_cast<__unsafe_unretained id *>(vp)); 209 __strong id *sip3 = reinterpret_cast<id *>(reinterpret_cast<__strong id *>(vp)); 210 __weak id *wip3 = reinterpret_cast<id *>(reinterpret_cast<__weak id *>(vp)); 211 __autoreleasing id *aip3 = reinterpret_cast<id *>(reinterpret_cast<__autoreleasing id *>(vp)); 212 __unsafe_unretained id *uip3 = reinterpret_cast<id *>(reinterpret_cast<__unsafe_unretained id *>(vp)); 213 214 Block_strong blk_strong1; 215 Block_strong blk_strong2 = static_cast<Block>(blk_strong1); 216 Block_autoreleasing *blk_auto = static_cast<Block*>(pblk); 217} 218