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