xref: /aosp_15_r20/external/clang/test/SemaObjCXX/blocks.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
2*67e74705SXin Li@protocol NSObject;
3*67e74705SXin Li
4*67e74705SXin Livoid bar(id(^)(void));
5*67e74705SXin Livoid foo(id <NSObject>(^objectCreationBlock)(void)) {
6*67e74705SXin Li    return bar(objectCreationBlock); // OK
7*67e74705SXin Li}
8*67e74705SXin Li
9*67e74705SXin Livoid bar2(id(*)(void));
10*67e74705SXin Livoid foo2(id <NSObject>(*objectCreationBlock)(void)) {
11*67e74705SXin Li    return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id<NSObject> (*)()' to parameter of type 'id (*)()'}}
12*67e74705SXin Li}
13*67e74705SXin Li
14*67e74705SXin Livoid bar3(id(*)()); // expected-note{{candidate function}}
15*67e74705SXin Livoid foo3(id (*objectCreationBlock)(int)) {
16*67e74705SXin Li    return bar3(objectCreationBlock); // expected-error{{no matching}}
17*67e74705SXin Li}
18*67e74705SXin Li
19*67e74705SXin Livoid bar4(id(^)()); // expected-note{{candidate function}}
20*67e74705SXin Livoid foo4(id (^objectCreationBlock)(int)) {
21*67e74705SXin Li    return bar4(objectCreationBlock); // expected-error{{no matching}}
22*67e74705SXin Li}
23*67e74705SXin Li
24*67e74705SXin Livoid foo5(id (^x)(int)) {
25*67e74705SXin Li  if (x) { }
26*67e74705SXin Li}
27*67e74705SXin Li
28*67e74705SXin Li// <rdar://problem/6590445>
29*67e74705SXin Li@interface Foo {
30*67e74705SXin Li    @private
31*67e74705SXin Li    void (^_block)(void);
32*67e74705SXin Li}
33*67e74705SXin Li- (void)bar;
34*67e74705SXin Li@end
35*67e74705SXin Li
36*67e74705SXin Linamespace N {
37*67e74705SXin Li  class X { };
38*67e74705SXin Li  void foo(X);
39*67e74705SXin Li}
40*67e74705SXin Li
41*67e74705SXin Li@implementation Foo
42*67e74705SXin Li- (void)bar {
43*67e74705SXin Li    _block();
44*67e74705SXin Li    foo(N::X()); // okay
45*67e74705SXin Li}
46*67e74705SXin Li@end
47*67e74705SXin Li
48*67e74705SXin Litypedef signed char BOOL;
49*67e74705SXin Livoid foo6(void *block) {
50*67e74705SXin Li	void (^vb)(id obj, int idx, BOOL *stop) = (void (^)(id, int, BOOL *))block;
51*67e74705SXin Li    BOOL (^bb)(id obj, int idx, BOOL *stop) = (BOOL (^)(id, int, BOOL *))block;
52*67e74705SXin Li}
53*67e74705SXin Li
54*67e74705SXin Li// <rdar://problem/8600419>: Require that the types of block
55*67e74705SXin Li// parameters are complete.
56*67e74705SXin Linamespace N1 {
57*67e74705SXin Li  template<class _T> class ptr; // expected-note{{template is declared here}}
58*67e74705SXin Li
59*67e74705SXin Li  template<class _T>
60*67e74705SXin Li    class foo {
61*67e74705SXin Li  public:
62*67e74705SXin Li    void bar(void (^)(ptr<_T>));
63*67e74705SXin Li  };
64*67e74705SXin Li
65*67e74705SXin Li  class X;
66*67e74705SXin Li
67*67e74705SXin Li  void test2();
68*67e74705SXin Li
69*67e74705SXin Li  void test()
70*67e74705SXin Li  {
71*67e74705SXin Li    foo<X> f;
72*67e74705SXin Li    f.bar(^(ptr<X> _f) { // expected-error{{implicit instantiation of undefined template 'N1::ptr<N1::X>'}}
73*67e74705SXin Li        test2();
74*67e74705SXin Li      });
75*67e74705SXin Li  }
76*67e74705SXin Li}
77*67e74705SXin Li
78*67e74705SXin Li// Make sure we successfully instantiate the copy constructor of a
79*67e74705SXin Li// __block variable's type.
80*67e74705SXin Linamespace N2 {
81*67e74705SXin Li  template <int n> struct A {
82*67e74705SXin Li    A() {}
83*67e74705SXin Li    A(const A &other) {
84*67e74705SXin Li      int invalid[-n]; // expected-error 2 {{array with a negative size}}
85*67e74705SXin Li    }
86*67e74705SXin Li  };
87*67e74705SXin Li
88*67e74705SXin Li  void test1() {
89*67e74705SXin Li    __block A<1> x; // expected-note {{requested here}}
90*67e74705SXin Li  }
91*67e74705SXin Li
92*67e74705SXin Li  template <int n> void test2() {
93*67e74705SXin Li    __block A<n> x; // expected-note {{requested here}}
94*67e74705SXin Li  }
95*67e74705SXin Li  template void test2<2>();
96*67e74705SXin Li}
97*67e74705SXin Li
98*67e74705SXin Li// Handle value-dependent block declaration references.
99*67e74705SXin Linamespace N3 {
100*67e74705SXin Li  template<int N> struct X { };
101*67e74705SXin Li
102*67e74705SXin Li  template<int N>
103*67e74705SXin Li  void f() {
104*67e74705SXin Li    X<N> xN = ^() { return X<N>(); }();
105*67e74705SXin Li  }
106*67e74705SXin Li}
107*67e74705SXin Li
108*67e74705SXin Li// rdar://8979379
109*67e74705SXin Li
110*67e74705SXin Li@interface A
111*67e74705SXin Li@end
112*67e74705SXin Li
113*67e74705SXin Li@interface B : A
114*67e74705SXin Li@end
115*67e74705SXin Li
116*67e74705SXin Livoid f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no known conversion from 'int (^)(B *)' to 'int (^)(A *)' for 1st argument}}
117*67e74705SXin Li
118*67e74705SXin Livoid g() {
119*67e74705SXin Li  f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}}
120*67e74705SXin Li}
121*67e74705SXin Li
122*67e74705SXin Linamespace DependentReturn {
123*67e74705SXin Li  template<typename T>
124*67e74705SXin Li  void f(T t) {
125*67e74705SXin Li    (void)^(T u) {
126*67e74705SXin Li      if (t != u)
127*67e74705SXin Li        return t + u;
128*67e74705SXin Li      else
129*67e74705SXin Li        return;
130*67e74705SXin Li    };
131*67e74705SXin Li
132*67e74705SXin Li    (void)^(T u) {
133*67e74705SXin Li      if (t == u)
134*67e74705SXin Li        return;
135*67e74705SXin Li      else
136*67e74705SXin Li        return t + u;
137*67e74705SXin Li    };
138*67e74705SXin Li  }
139*67e74705SXin Li
140*67e74705SXin Li  struct X { };
141*67e74705SXin Li  void operator+(X, X);
142*67e74705SXin Li  bool operator==(X, X);
143*67e74705SXin Li  bool operator!=(X, X);
144*67e74705SXin Li
145*67e74705SXin Li  template void f<X>(X);
146*67e74705SXin Li}
147