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