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