1 // RUN: %clang_cc1 -fobjc-nonfragile-abi -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{{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 27 namespace rdar8898937 { 28 29 typedef void (^dispatch_block_t)(void); 30 31 void dispatch_once(dispatch_block_t block); 32 static void _dispatch_once(dispatch_block_t block) 33 { 34 dispatch_once(block); 35 } 36 37 } 38 39 void 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 56 void 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 68 void 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 82 void 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 102 void 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 126 void 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 139 void 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 173 void 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 198 typedef void (^Block)(); 199 typedef void (^Block_strong)() __strong; 200 typedef void (^Block_autoreleasing)() __autoreleasing; 201 202 @class NSString; 203 204 void ownership_transfer_in_cast(void *vp, Block *pblk) { 205 __strong NSString **sip2 = static_cast<NSString **>(static_cast<__strong id *>(vp)); 206 __strong NSString **&si2pref = static_cast<NSString **&>(sip2); 207 __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 } 219 220 // Make sure we don't crash. 221 void writeback_test(NSString & &) {} // expected-error {{type name declared as a reference to a reference}} 222