1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s 2// test for block type safety. 3 4@interface Super @end 5@interface Sub : Super @end 6 7void f2(void(^f)(Super *)) { // expected-note{{passing argument to parameter 'f' here}} 8 Super *o; 9 f(o); 10} 11 12void f3(void(^f)(Sub *)) { 13 Sub *o; 14 f(o); 15} 16 17void r0(Super* (^f)()) { 18 Super *o = f(); 19} 20 21void r1(Sub* (^f)()) { // expected-note{{passing argument to parameter 'f' here}} 22 Sub *o = f(); 23} 24 25@protocol NSObject; 26 27void r2 (id<NSObject> (^f) (void)) { 28 id o = f(); 29} 30 31void 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 50void f0(void (^f)(A* x)) { 51 A* a; 52 f(a); 53} 54 55void f1(void (^f)(id x)) { 56 B *b; 57 f(b); 58} 59 60void 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; 98void 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 103void 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 117int 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 134int test5() { 135 NSAllArray *(^block)(id); 136 id <Foo> (^genericBlock)(id); 137 genericBlock = block; 138 return 0; 139} 140 141// rdar://10798770 142typedef int NSInteger; 143 144typedef enum : NSInteger {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending} NSComparisonResult; 145 146typedef NSComparisonResult (^NSComparator)(id obj1, id obj2); 147 148@interface radar10798770 149- (void)sortUsingComparator:(NSComparator)c; 150@end 151 152void f() { 153 radar10798770 *f; 154 [f sortUsingComparator:^(id a, id b) { 155 return NSOrderedSame; 156 }]; 157} 158