| 1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s |
| 2 | |
| 3 | typedef const void *CFTypeRef; |
| 4 | typedef const struct __CFString *CFStringRef; |
| 5 | |
| 6 | @interface NSString |
| 7 | @end |
| 8 | |
| 9 | CFTypeRef CFCreateSomething(); |
| 10 | CFStringRef CFCreateString(); |
| 11 | CFTypeRef CFGetSomething(); |
| 12 | CFStringRef CFGetString(); |
| 13 | |
| 14 | id CreateSomething(); |
| 15 | NSString *CreateNSString(); |
| 16 | |
| 17 | template<typename IdType, typename StringType, typename IntPtrType> |
| 18 | void from_cf() { |
| 19 | id obj1 = (__bridge_transfer IdType)CFCreateSomething(); |
| 20 | id obj2 = (__bridge_transfer StringType)CFCreateString(); |
| 21 | (__bridge IntPtrType)CFCreateSomething(); // expected-error{{incompatible types casting 'CFTypeRef' (aka 'const void *') to 'int *' with a __bridge cast}} |
| 22 | id obj3 = (__bridge IdType)CFGetSomething(); |
| 23 | id obj4 = (__bridge StringType)CFGetString(); |
| 24 | } |
| 25 | |
| 26 | template void from_cf<id, NSString*, int*>(); // expected-note{{in instantiation of function template specialization}} |
| 27 | |
| 28 | template<typename IdType, typename StringType> |
| 29 | void to_cf(id obj) { |
| 30 | CFTypeRef cf1 = (__bridge_retained IdType)CreateSomething(); |
| 31 | CFStringRef cf2 = (__bridge_retained StringType)CreateNSString(); |
| 32 | CFTypeRef cf3 = (__bridge IdType)CreateSomething(); |
| 33 | CFStringRef cf4 = (__bridge StringType)CreateNSString(); |
| 34 | } |
| 35 | |
| 36 | template void to_cf<CFTypeRef, CFStringRef>(id); |
| 37 | |
| 38 | // rdar://problem/20107345 |
| 39 | typedef const struct __attribute__((objc_bridge(id))) __CFAnnotatedObject *CFAnnotatedObjectRef; |
| 40 | CFAnnotatedObjectRef CFGetAnnotated(); |
| 41 | |
| 42 | void testObjCBridgeId() { |
| 43 | id obj; |
| 44 | obj = (__bridge id)CFGetAnnotated(); |
| 45 | obj = (__bridge NSString*)CFGetAnnotated(); |
| 46 | obj = (__bridge_transfer id)CFGetAnnotated(); |
| 47 | obj = (__bridge_transfer NSString*)CFGetAnnotated(); |
| 48 | |
| 49 | CFAnnotatedObjectRef ref; |
| 50 | ref = (__bridge CFAnnotatedObjectRef) CreateSomething(); |
| 51 | ref = (__bridge CFAnnotatedObjectRef) CreateNSString(); |
| 52 | ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething(); |
| 53 | ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString(); |
| 54 | } |
| 55 | |
| 56 | struct __CFAnnotatedObject { |
| 57 | } cf0; |
| 58 | |
| 59 | extern const CFAnnotatedObjectRef r0; |
| 60 | extern const CFAnnotatedObjectRef r1 = &cf0; |
| 61 | extern "C" const CFAnnotatedObjectRef r2; |
| 62 | extern "C" const CFAnnotatedObjectRef r3 = &cf0; |
| 63 | |
| 64 | void testExternC() { |
| 65 | id obj; |
| 66 | obj = (id)r0; |
| 67 | obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} |
| 68 | obj = (id)r2; |
| 69 | obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} |
| 70 | } |
| 71 | |