John McCall | 9f084a3 | 2011-07-06 00:26:06 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks %s |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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}} |
Argyrios Kyrtzidis | 0a85183 | 2011-07-01 22:22:59 +0000 | [diff] [blame] | 10 | (void)(id*)arg; // expected-error{{C-style cast from 'id' to '__strong id *' casts away qualifiers}} |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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 *'}} |
Argyrios Kyrtzidis | 31862ba | 2011-07-01 22:22:50 +0000 | [diff] [blame] | 44 | (void)static_cast<id*>(arg); // expected-error {{cannot cast from type 'id' to pointer type '__strong id *'}} |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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) { |
Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 58 | // Cannot use const_cast to cast between ownership qualifications or |
| 59 | // add/remove ownership qualifications. |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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) { |
Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 70 | // Okay to reinterpret_cast to add/remove/change ownership |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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) { |
Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 84 | // C-style casts aren't allowed to change Objective-C ownership |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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) { |
Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 104 | // Functional casts aren't allowed to change Objective-C ownership |
John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 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 | } |
Argyrios Kyrtzidis | 31862ba | 2011-07-01 22:22:50 +0000 | [diff] [blame] | 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)); |
Argyrios Kyrtzidis | 28445f0 | 2011-07-01 23:01:46 +0000 | [diff] [blame] | 206 | __strong NSString **&si2pref = static_cast<NSString **&>(sip2); |
Argyrios Kyrtzidis | 31862ba | 2011-07-01 22:22:50 +0000 | [diff] [blame] | 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 | } |
Argyrios Kyrtzidis | 1c73dcb | 2011-07-01 22:23:03 +0000 | [diff] [blame] | 219 | |
| 220 | // Make sure we don't crash. |
| 221 | void writeback_test(NSString & &) {} // expected-error {{type name declared as a reference to a reference}} |