1 // RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks 2 // test for block type safety. 3 4 @interface Super @end 5 @interface Sub : Super @end 6 7 void f2(void(^f)(Super *)) { // expected-note{{passing argument to parameter 'f' here}} 8 Super *o; 9 f(o); 10 } 11 12 void f3(void(^f)(Sub *)) { 13 Sub *o; 14 f(o); 15 } 16 17 void r0(Super* (^f)()) { 18 Super *o = f(); 19 } 20 21 void r1(Sub* (^f)()) { // expected-note{{passing argument to parameter 'f' here}} 22 Sub *o = f(); 23 } 24 25 @protocol NSObject; 26 27 void r2 (id<NSObject> (^f) (void)) { 28 id o = f(); 29 } 30 31 void test1() { 32 f2(^(Sub *o) { }); // expected-error {{incompatible block pointer types passing}} 33 f3(^(Super *o) { }); // OK, block taking Super* may be called with a Sub* 34 35 r0(^Super* () { return 0; }); // OK 36 r0(^Sub* () { return 0; }); // OK, variable of type Super* gets return value of type Sub* 37 r0(^id () { return 0; }); 38 39 r1(^Super* () { return 0; }); // expected-error {{incompatible block pointer types passing}} 40 r1(^Sub* () { return 0; }); // OK 41 r1(^id () { return 0; }); 42 43 r2(^id<NSObject>() { return 0; }); 44 } 45 46 47 @interface A @end 48 @interface B @end 49 50 void f0(void (^f)(A* x)) { 51 A* a; 52 f(a); 53 } 54 55 void f1(void (^f)(id x)) { 56 B *b; 57 f(b); 58 } 59 60 void test2(void) 61 { 62 f0(^(id a) { }); // OK 63 f1(^(A* a) { }); 64 f1(^(id<NSObject> a) { }); // OK 65 } 66 67 @interface NSArray 68 // Calls block() with every object in the array 69 -enumerateObjectsWithBlock:(void (^)(id obj))block; 70 @end 71 72 @interface MyThing 73 -(void) printThing; 74 @end 75 76 @implementation MyThing 77 static NSArray* myThings; // array of MyThing* 78 79 -(void) printThing { } 80 81 // programmer wants to write this: 82 -printMyThings1 { 83 [myThings enumerateObjectsWithBlock: ^(MyThing *obj) { 84 [obj printThing]; 85 }]; 86 } 87 88 // strict type safety requires this: 89 -printMyThings { 90 [myThings enumerateObjectsWithBlock: ^(id obj) { 91 MyThing *obj2 = (MyThing *)obj; 92 [obj2 printThing]; 93 }]; 94 } 95 @end 96 97 @protocol P, P2; 98 void f4(void (^f)(id<P> x)) { // expected-note{{passing argument to parameter 'f' here}} 99 NSArray<P2> *b; 100 f(b); // expected-warning {{passing 'NSArray<P2> *' to parameter of incompatible type 'id<P>'}} 101 } 102 103 void test3() { 104 f4(^(NSArray<P2>* a) { }); // expected-error {{incompatible block pointer types passing 'void (^)(NSArray<P2> *)' to parameter of type 'void (^)(id<P>)'}} 105 } 106 107 // rdar : //8302845 108 @protocol Foo @end 109 110 @interface Baz @end 111 112 @interface Baz(FooConformance) <Foo> 113 @end 114 115 @implementation Baz @end 116 117 int test4 () { 118 id <Foo> (^b)() = ^{ // Doesn't work 119 return (Baz *)0; 120 }; 121 return 0; 122 } 123 124 // rdar:// 9118343 125 126 @protocol NSCopying @end 127 128 @interface NSAllArray <NSCopying> 129 @end 130 131 @interface NSAllArray (FooConformance) <Foo> 132 @end 133 134 int test5() { 135 NSAllArray *(^block)(id); 136 id <Foo> (^genericBlock)(id); 137 genericBlock = block; 138 return 0; 139 } 140 141