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