• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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