Home | History | Annotate | Download | only in expr.prim.lambda
      1 // RUN: %clang_cc1 -triple i686-pc-linux -std=c++11 -fblocks %s -verify
      2 
      3 void block_capture_errors() {
      4   __block int var; // expected-note 2{{'var' declared here}}
      5   (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
      6 
      7   (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}}
      8 }
      9 
     10 void conversion_to_block(int captured) {
     11   int (^b1)(int) = [=](int x) { return x + captured; };
     12 
     13   const auto lambda = [=](int x) { return x + captured; };
     14   int (^b2)(int) = lambda;
     15 }
     16 
     17 template<typename T>
     18 class ConstCopyConstructorBoom {
     19 public:
     20   ConstCopyConstructorBoom(ConstCopyConstructorBoom&);
     21 
     22   ConstCopyConstructorBoom(const ConstCopyConstructorBoom&) {
     23     T *ptr = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
     24   }
     25 
     26   void foo() const;
     27 };
     28 
     29 void conversion_to_block_init(ConstCopyConstructorBoom<int> boom,
     30                               ConstCopyConstructorBoom<float> boom2) {
     31   const auto& lambda1([=] { boom.foo(); }); // okay
     32 
     33   const auto& lambda2([=] { boom2.foo(); }); // expected-note{{in instantiation of member function}}
     34   void (^block)(void) = lambda2;
     35 }
     36 
     37 
     38 void nesting() {
     39   int array[7]; // expected-note 2{{'array' declared here}}
     40   [=] () mutable {
     41     [&] {
     42       ^ {
     43         int i = array[2];
     44         i += array[3];
     45       }();
     46     }();
     47   }();
     48 
     49   [&] {
     50     [=] () mutable {
     51       ^ {
     52         int i = array[2]; // expected-error{{cannot refer to declaration with an array type inside block}}
     53         i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}}
     54       }();
     55     }();
     56   }();
     57 }
     58 
     59 namespace overloading {
     60   void bool_conversion() {
     61     if ([](){}) {
     62     }
     63 
     64     bool b = []{};
     65     b = (bool)[]{};
     66   }
     67 
     68   void conversions() {
     69     int (*fp)(int) = [](int x) { return x + 1; };
     70     fp = [](int x) { return x + 1; };
     71 
     72     typedef int (*func_ptr)(int);
     73     fp = (func_ptr)[](int x) { return x + 1; };
     74 
     75     int (^bp)(int) = [](int x) { return x + 1; };
     76     bp = [](int x) { return x + 1; };
     77 
     78     typedef int (^block_ptr)(int);
     79     bp = (block_ptr)[](int x) { return x + 1; };
     80   }
     81 
     82   int &accept_lambda_conv(int (*fp)(int));
     83   float &accept_lambda_conv(int (^bp)(int));
     84 
     85   void call_with_lambda() {
     86     int &ir = accept_lambda_conv([](int x) { return x + 1; });
     87   }
     88 
     89   template<typename T> using id = T;
     90 
     91   auto a = [](){};
     92   struct C : decltype(a) {
     93     using decltype(a)::operator id<void(*)()>;
     94   private:
     95     using decltype(a)::operator id<void(^)()>;
     96   } extern c;
     97 
     98   struct D : decltype(a) {
     99     using decltype(a)::operator id<void(^)()>;
    100   private:
    101     using decltype(a)::operator id<void(*)()>; // expected-note {{here}}
    102   } extern d;
    103 
    104   bool r1 = c;
    105   bool r2 = d; // expected-error {{private}}
    106 }
    107 
    108 namespace PR13117 {
    109   struct A {
    110     template<typename ... Args> static void f(Args...);
    111 
    112     template<typename ... Args> static void f1()
    113     {
    114       (void)^(Args args) { // expected-error{{block contains unexpanded parameter pack 'Args'}}
    115       };
    116     }
    117 
    118     template<typename ... Args> static void f2()
    119     {
    120       // FIXME: Allow this.
    121       f(
    122         ^(Args args) // expected-error{{block contains unexpanded parameter pack 'Args'}}
    123         { }
    124         ... // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
    125       );
    126     }
    127 
    128     template<typename ... Args> static void f3()
    129     {
    130       (void)[](Args args) { // expected-error{{expression contains unexpanded parameter pack 'Args'}}
    131       };
    132     }
    133 
    134     template<typename ... Args> static void f4()
    135     {
    136       f([](Args args) { } ...);
    137     }
    138   };
    139 
    140   void g() {
    141     A::f1<int, int>();
    142     A::f2<int, int>();
    143   }
    144 }
    145