1// RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s 2 3void * cvt(id arg) // expected-note{{candidate function not viable: cannot convert argument of incomplete type 'void *' to '__strong id'}} 4{ 5 void* voidp_val; 6 (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}} 7 (void)(id)arg; 8 (void)(__autoreleasing id*)arg; // expected-error{{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}} 9 (void)(id*)arg; // expected-error{{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}} 10 11 (void)(__autoreleasing id**)voidp_val; 12 (void)(void*)voidp_val; 13 (void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed}} 14 cvt((void*)arg); // expected-error {{no matching function for call to 'cvt'}} 15 cvt(0); 16 (void)(__strong id**)(0); 17 18 // FIXME: Diagnostic could be better here. 19 return arg; // expected-error{{cannot initialize return object of type 'void *' with an lvalue of type '__strong id'}} 20} 21 22namespace rdar8898937 { 23 24typedef void (^dispatch_block_t)(void); 25 26void dispatch_once(dispatch_block_t block); 27static void _dispatch_once(dispatch_block_t block) 28{ 29 dispatch_once(block); 30} 31 32} 33 34void static_casts(id arg) { 35 void* voidp_val; 36 (void)static_cast<int*>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'int *'}} 37 (void)static_cast<id>(arg); 38 (void)static_cast<__autoreleasing id*>(arg); // expected-error{{cannot cast from type 'id' to pointer type '__autoreleasing id *'}} 39 (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__strong id *'}} 40 41 (void)static_cast<__autoreleasing id**>(voidp_val); 42 (void)static_cast<void*>(voidp_val); 43 (void)static_cast<void**>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'void **'}} 44 (void)static_cast<__strong id**>(0); 45 46 __strong id *idp; 47 (void)static_cast<__autoreleasing id*>(idp); // expected-error{{static_cast from '__strong id *' to '__autoreleasing id *' is not allowed}} 48 (void)static_cast<__weak id*>(idp); // expected-error{{static_cast from '__strong id *' to '__weak id *' is not allowed}} 49} 50 51void test_const_cast(__strong id *sip, __weak id *wip, 52 const __strong id *csip, __weak const id *cwip) { 53 // Cannot use const_cast to cast between ownership qualifications or 54 // add/remove ownership qualifications. 55 (void)const_cast<__strong id *>(wip); // expected-error{{is not allowed}} 56 (void)const_cast<__weak id *>(sip); // expected-error{{is not allowed}} 57 58 // It's acceptable to cast away constness. 59 (void)const_cast<__strong id *>(csip); 60 (void)const_cast<__weak id *>(cwip); 61} 62 63void test_reinterpret_cast(__strong id *sip, __weak id *wip, 64 const __strong id *csip, __weak const id *cwip) { 65 // Okay to reinterpret_cast to add/remove/change ownership 66 // qualifications. 67 (void)reinterpret_cast<__strong id *>(wip); 68 (void)reinterpret_cast<__weak id *>(sip); 69 70 // Not allowed to cast away constness 71 (void)reinterpret_cast<__strong id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__strong id *' casts away qualifiers}} 72 (void)reinterpret_cast<__weak id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__weak id *' casts away qualifiers}} 73 (void)reinterpret_cast<__weak id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__weak id *' casts away qualifiers}} 74 (void)reinterpret_cast<__strong id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__strong id *' casts away qualifiers}} 75} 76 77void test_cstyle_cast(__strong id *sip, __weak id *wip, 78 const __strong id *csip, __weak const id *cwip) { 79 // C-style casts aren't allowed to change Objective-C ownership 80 // qualifiers (beyond what the normal implicit conversion allows). 81 82 (void)(__strong id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id *' casts away qualifiers}} 83 (void)(__strong id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id *' casts away qualifiers}} 84 (void)(__weak id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id *' casts away qualifiers}} 85 (void)(__weak id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id *' casts away qualifiers}} 86 87 (void)(__strong const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id const *' casts away qualifiers}} 88 (void)(__strong const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id const *' casts away qualifiers}} 89 (void)(__weak const id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id const *' casts away qualifiers}} 90 (void)(__weak const id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id const *' casts away qualifiers}} 91 (void)(__autoreleasing const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__autoreleasing id const *' casts away qualifiers}} 92 (void)(__autoreleasing const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__autoreleasing id const *' casts away qualifiers}} 93 (void)(__autoreleasing const id *)sip; 94 (void)(__autoreleasing const id *)csip; 95} 96 97void test_functional_cast(__strong id *sip, __weak id *wip, 98 __autoreleasing id *aip) { 99 // Functional casts aren't allowed to change Objective-C ownership 100 // qualifiers (beyond what the normal implicit conversion allows). 101 102 typedef __strong id *strong_id_pointer; 103 typedef __weak id *weak_id_pointer; 104 typedef __autoreleasing id *autoreleasing_id_pointer; 105 106 typedef const __strong id *const_strong_id_pointer; 107 typedef const __weak id *const_weak_id_pointer; 108 typedef const __autoreleasing id *const_autoreleasing_id_pointer; 109 110 (void)strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'strong_id_pointer' (aka '__strong id *') casts away qualifiers}} 111 (void)weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'weak_id_pointer' (aka '__weak id *') casts away qualifiers}} 112 (void)autoreleasing_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} 113 (void)autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} 114 (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}} 115 (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}} 116 (void)const_autoreleasing_id_pointer(sip); 117 (void)const_autoreleasing_id_pointer(aip); 118 (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}} 119} 120 121void test_unsafe_unretained(__strong id *sip, __weak id *wip, 122 __autoreleasing id *aip, 123 __unsafe_unretained id *uip, 124 const __unsafe_unretained id *cuip) { 125 uip = sip; // expected-error{{assigning '__strong id *' to '__unsafe_unretained id *' changes retain/release properties of pointer}} 126 uip = wip; // expected-error{{assigning '__weak id *' to '__unsafe_unretained id *' changes retain/release properties of pointer}} 127 uip = aip; // expected-error{{assigning '__autoreleasing id *' to '__unsafe_unretained id *' changes retain/release properties of pointer}} 128 129 cuip = sip; 130 cuip = wip; // expected-error{{assigning '__weak id *' to '__unsafe_unretained id const *' changes retain/release properties of pointer}} 131 cuip = aip; 132} 133 134void to_void(__strong id *sip, __weak id *wip, 135 __autoreleasing id *aip, 136 __unsafe_unretained id *uip) { 137 void *vp1 = sip; 138 void *vp2 = wip; 139 void *vp3 = aip; 140 void *vp4 = uip; 141 (void)(void*)sip; 142 (void)(void*)wip; 143 (void)(void*)aip; 144 (void)(void*)uip; 145 (void)static_cast<void*>(sip); 146 (void)static_cast<void*>(wip); 147 (void)static_cast<void*>(aip); 148 (void)static_cast<void*>(uip); 149 (void)reinterpret_cast<void*>(sip); 150 (void)reinterpret_cast<void*>(wip); 151 (void)reinterpret_cast<void*>(aip); 152 (void)reinterpret_cast<void*>(uip); 153 154 (void)(void*)&sip; 155 (void)(void*)&wip; 156 (void)(void*)&aip; 157 (void)(void*)&uip; 158 (void)static_cast<void*>(&sip); 159 (void)static_cast<void*>(&wip); 160 (void)static_cast<void*>(&aip); 161 (void)static_cast<void*>(&uip); 162 (void)reinterpret_cast<void*>(&sip); 163 (void)reinterpret_cast<void*>(&wip); 164 (void)reinterpret_cast<void*>(&aip); 165 (void)reinterpret_cast<void*>(&uip); 166} 167 168void from_void(void *vp) { 169 __strong id *sip = (__strong id *)vp; 170 __weak id *wip = (__weak id *)vp; 171 __autoreleasing id *aip = (__autoreleasing id *)vp; 172 __unsafe_unretained id *uip = (__unsafe_unretained id *)vp; 173 __strong id *sip2 = static_cast<__strong id *>(vp); 174 __weak id *wip2 = static_cast<__weak id *>(vp); 175 __autoreleasing id *aip2 = static_cast<__autoreleasing id *>(vp); 176 __unsafe_unretained id *uip2 = static_cast<__unsafe_unretained id *>(vp); 177 __strong id *sip3 = reinterpret_cast<__strong id *>(vp); 178 __weak id *wip3 = reinterpret_cast<__weak id *>(vp); 179 __autoreleasing id *aip3 = reinterpret_cast<__autoreleasing id *>(vp); 180 __unsafe_unretained id *uip3 = reinterpret_cast<__unsafe_unretained id *>(vp); 181 182 __strong id **sipp = (__strong id **)vp; 183 __weak id **wipp = (__weak id **)vp; 184 __autoreleasing id **aipp = (__autoreleasing id **)vp; 185 __unsafe_unretained id **uipp = (__unsafe_unretained id **)vp; 186 187 sip = vp; // expected-error{{assigning to '__strong id *' from incompatible type 'void *'}} 188 wip = vp; // expected-error{{assigning to '__weak id *' from incompatible type 'void *'}} 189 aip = vp; // expected-error{{assigning to '__autoreleasing id *' from incompatible type 'void *'}} 190 uip = vp; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type 'void *'}} 191} 192 193typedef void (^Block)(); 194typedef void (^Block_strong)() __strong; 195typedef void (^Block_autoreleasing)() __autoreleasing; 196 197@class NSString; 198 199void ownership_transfer_in_cast(void *vp, Block *pblk) { 200 __strong NSString **sip2 = static_cast<NSString **>(static_cast<__strong id *>(vp)); 201 __strong NSString **&si2pref = static_cast<NSString **&>(sip2); 202 __weak NSString **wip2 = static_cast<NSString **>(static_cast<__weak id *>(vp)); 203 __autoreleasing id *aip2 = static_cast<id *>(static_cast<__autoreleasing id *>(vp)); 204 __unsafe_unretained id *uip2 = static_cast<id *>(static_cast<__unsafe_unretained id *>(vp)); 205 __strong id *sip3 = reinterpret_cast<id *>(reinterpret_cast<__strong id *>(vp)); 206 __weak id *wip3 = reinterpret_cast<id *>(reinterpret_cast<__weak id *>(vp)); 207 __autoreleasing id *aip3 = reinterpret_cast<id *>(reinterpret_cast<__autoreleasing id *>(vp)); 208 __unsafe_unretained id *uip3 = reinterpret_cast<id *>(reinterpret_cast<__unsafe_unretained id *>(vp)); 209 210 Block_strong blk_strong1; 211 Block_strong blk_strong2 = static_cast<Block>(blk_strong1); 212 Block_autoreleasing *blk_auto = static_cast<Block*>(pblk); 213} 214 215// Make sure we don't crash. 216void writeback_test(NSString & &) {} // expected-error {{type name declared as a reference to a reference}} 217 218void test_strong_opaque() { 219 __strong NSString *sptr; 220 void *vptr; 221 222 (void)(0 ? sptr : vptr); // expected-error{{operands to conditional of types 'NSString *' and 'void *' are incompatible in ARC mode}} 223} 224