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{{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 {{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