arc-type-conversion.mm revision f85e193739c953358c865005855253af4f68a497
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 {{pointer to non-const type 'id' with no explicit lifetime}} \ 11 // expected-error{{C-style cast from 'id' to '__autoreleasing id *' casts away qualifiers}} 12 13 (void)(__autoreleasing id**)voidp_val; 14 (void)(void*)voidp_val; 15 (void)(void**)arg; // expected-error {{cast of an Objective-C pointer to 'void **' is disallowed}} 16 cvt((void*)arg); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} \ 17 // expected-error {{no matching function for call to 'cvt'}} \ 18 // expected-note{{use __bridge to convert directly (no change in ownership)}} \ 19 // expected-note{{use __bridge_retained to make an ARC object available as a +1 'void *'}} 20 cvt(0); 21 (void)(__strong id**)(0); 22 23 // FIXME: Diagnostic could be better here. 24 return arg; // expected-error{{cannot initialize return object of type 'void *' with an lvalue of type '__strong id'}} 25} 26 27// rdar://8898937 28namespace rdar8898937 { 29 30typedef void (^dispatch_block_t)(void); 31 32void dispatch_once(dispatch_block_t block); 33static void _dispatch_once(dispatch_block_t block) 34{ 35 dispatch_once(block); 36} 37 38} 39 40void static_casts(id arg) { 41 void* voidp_val; 42 (void)static_cast<int*>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'int *'}} 43 (void)static_cast<id>(arg); 44 (void)static_cast<__autoreleasing id*>(arg); // expected-error{{cannot cast from type 'id' to pointer type '__autoreleasing id *'}} 45 (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__autoreleasing id *'}} \ 46 // expected-error{{pointer to non-const type 'id' with no explicit lifetime}} 47 48 (void)static_cast<__autoreleasing id**>(voidp_val); 49 (void)static_cast<void*>(voidp_val); 50 (void)static_cast<void**>(arg); // expected-error {{cannot cast from type 'id' to pointer type 'void **'}} 51 (void)static_cast<__strong id**>(0); 52 53 __strong id *idp; 54 (void)static_cast<__autoreleasing id*>(idp); // expected-error{{static_cast from '__strong id *' to '__autoreleasing id *' is not allowed}} 55 (void)static_cast<__weak id*>(idp); // expected-error{{static_cast from '__strong id *' to '__weak id *' is not allowed}} 56} 57 58void test_const_cast(__strong id *sip, __weak id *wip, 59 const __strong id *csip, __weak const id *cwip) { 60 // Cannot use const_cast to cast between lifetime qualifications or 61 // add/remove lifetime qualifications. 62 (void)const_cast<__strong id *>(wip); // expected-error{{is not allowed}} 63 (void)const_cast<__weak id *>(sip); // expected-error{{is not allowed}} 64 65 // It's acceptable to cast away constness. 66 (void)const_cast<__strong id *>(csip); 67 (void)const_cast<__weak id *>(cwip); 68} 69 70void test_reinterpret_cast(__strong id *sip, __weak id *wip, 71 const __strong id *csip, __weak const id *cwip) { 72 // Okay to reinterpret_cast to add/remove/change lifetime 73 // qualifications. 74 (void)reinterpret_cast<__strong id *>(wip); 75 (void)reinterpret_cast<__weak id *>(sip); 76 77 // Not allowed to cast away constness 78 (void)reinterpret_cast<__strong id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__strong id *' casts away qualifiers}} 79 (void)reinterpret_cast<__weak id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__weak id *' casts away qualifiers}} 80 (void)reinterpret_cast<__weak id *>(csip); // expected-error{{reinterpret_cast from '__strong id const *' to '__weak id *' casts away qualifiers}} 81 (void)reinterpret_cast<__strong id *>(cwip); // expected-error{{reinterpret_cast from '__weak id const *' to '__strong id *' casts away qualifiers}} 82} 83 84void test_cstyle_cast(__strong id *sip, __weak id *wip, 85 const __strong id *csip, __weak const id *cwip) { 86 // C-style casts aren't allowed to change Objective-C lifetime 87 // qualifiers (beyond what the normal implicit conversion allows). 88 89 (void)(__strong id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id *' casts away qualifiers}} 90 (void)(__strong id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id *' casts away qualifiers}} 91 (void)(__weak id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id *' casts away qualifiers}} 92 (void)(__weak id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id *' casts away qualifiers}} 93 94 (void)(__strong const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__strong id const *' casts away qualifiers}} 95 (void)(__strong const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__strong id const *' casts away qualifiers}} 96 (void)(__weak const id *)sip; // expected-error{{C-style cast from '__strong id *' to '__weak id const *' casts away qualifiers}} 97 (void)(__weak const id *)csip; // expected-error{{C-style cast from '__strong id const *' to '__weak id const *' casts away qualifiers}} 98 (void)(__autoreleasing const id *)wip; // expected-error{{C-style cast from '__weak id *' to '__autoreleasing id const *' casts away qualifiers}} 99 (void)(__autoreleasing const id *)cwip; // expected-error{{C-style cast from '__weak id const *' to '__autoreleasing id const *' casts away qualifiers}} 100 (void)(__autoreleasing const id *)sip; 101 (void)(__autoreleasing const id *)csip; 102} 103 104void test_functional_cast(__strong id *sip, __weak id *wip, 105 __autoreleasing id *aip) { 106 // Functional casts aren't allowed to change Objective-C lifetime 107 // qualifiers (beyond what the normal implicit conversion allows). 108 109 typedef __strong id *strong_id_pointer; 110 typedef __weak id *weak_id_pointer; 111 typedef __autoreleasing id *autoreleasing_id_pointer; 112 113 typedef const __strong id *const_strong_id_pointer; 114 typedef const __weak id *const_weak_id_pointer; 115 typedef const __autoreleasing id *const_autoreleasing_id_pointer; 116 117 (void)strong_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'strong_id_pointer' (aka '__strong id *') casts away qualifiers}} 118 (void)weak_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'weak_id_pointer' (aka '__weak id *') casts away qualifiers}} 119 (void)autoreleasing_id_pointer(sip); // expected-error{{functional-style cast from '__strong id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} 120 (void)autoreleasing_id_pointer(wip); // expected-error{{functional-style cast from '__weak id *' to 'autoreleasing_id_pointer' (aka '__autoreleasing id *') casts away qualifiers}} 121 (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}} 122 (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}} 123 (void)const_autoreleasing_id_pointer(sip); 124 (void)const_autoreleasing_id_pointer(aip); 125 (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}} 126} 127 128void test_unsafe_unretained(__strong id *sip, __weak id *wip, 129 __autoreleasing id *aip, 130 __unsafe_unretained id *uip, 131 const __unsafe_unretained id *cuip) { 132 uip = sip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__strong id *'}} 133 uip = wip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__weak id *'}} 134 uip = aip; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type '__autoreleasing id *'}} 135 136 cuip = sip; 137 cuip = wip; // expected-error{{assigning to '__unsafe_unretained id const *' from incompatible type '__weak id *'}} 138 cuip = aip; 139} 140 141void to_void(__strong id *sip, __weak id *wip, 142 __autoreleasing id *aip, 143 __unsafe_unretained id *uip) { 144 void *vp1 = sip; 145 void *vp2 = wip; 146 void *vp3 = aip; 147 void *vp4 = uip; 148 (void)(void*)sip; 149 (void)(void*)wip; 150 (void)(void*)aip; 151 (void)(void*)uip; 152 (void)static_cast<void*>(sip); 153 (void)static_cast<void*>(wip); 154 (void)static_cast<void*>(aip); 155 (void)static_cast<void*>(uip); 156 (void)reinterpret_cast<void*>(sip); 157 (void)reinterpret_cast<void*>(wip); 158 (void)reinterpret_cast<void*>(aip); 159 (void)reinterpret_cast<void*>(uip); 160 161 (void)(void*)&sip; 162 (void)(void*)&wip; 163 (void)(void*)&aip; 164 (void)(void*)&uip; 165 (void)static_cast<void*>(&sip); 166 (void)static_cast<void*>(&wip); 167 (void)static_cast<void*>(&aip); 168 (void)static_cast<void*>(&uip); 169 (void)reinterpret_cast<void*>(&sip); 170 (void)reinterpret_cast<void*>(&wip); 171 (void)reinterpret_cast<void*>(&aip); 172 (void)reinterpret_cast<void*>(&uip); 173} 174 175void from_void(void *vp) { 176 __strong id *sip = (__strong id *)vp; 177 __weak id *wip = (__weak id *)vp; 178 __autoreleasing id *aip = (__autoreleasing id *)vp; 179 __unsafe_unretained id *uip = (__unsafe_unretained id *)vp; 180 __strong id *sip2 = static_cast<__strong id *>(vp); 181 __weak id *wip2 = static_cast<__weak id *>(vp); 182 __autoreleasing id *aip2 = static_cast<__autoreleasing id *>(vp); 183 __unsafe_unretained id *uip2 = static_cast<__unsafe_unretained id *>(vp); 184 __strong id *sip3 = reinterpret_cast<__strong id *>(vp); 185 __weak id *wip3 = reinterpret_cast<__weak id *>(vp); 186 __autoreleasing id *aip3 = reinterpret_cast<__autoreleasing id *>(vp); 187 __unsafe_unretained id *uip3 = reinterpret_cast<__unsafe_unretained id *>(vp); 188 189 __strong id **sipp = (__strong id **)vp; 190 __weak id **wipp = (__weak id **)vp; 191 __autoreleasing id **aipp = (__autoreleasing id **)vp; 192 __unsafe_unretained id **uipp = (__unsafe_unretained id **)vp; 193 194 sip = vp; // expected-error{{assigning to '__strong id *' from incompatible type 'void *'}} 195 wip = vp; // expected-error{{assigning to '__weak id *' from incompatible type 'void *'}} 196 aip = vp; // expected-error{{assigning to '__autoreleasing id *' from incompatible type 'void *'}} 197 uip = vp; // expected-error{{assigning to '__unsafe_unretained id *' from incompatible type 'void *'}} 198} 199