Home | History | Annotate | Download | only in expr.prim.lambda
      1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify
      2 
      3 template<typename T>
      4 void test_attributes() {
      5   auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}}
      6 }
      7 
      8 template void test_attributes<int>(); // expected-note{{in instantiation of function}}
      9 
     10 template<typename T>
     11 void call_with_zero() {
     12   [](T *ptr) -> T& { return *ptr; }(0);
     13 }
     14 
     15 template void call_with_zero<int>();
     16 
     17 template<typename T>
     18 T captures(T x, T y) {
     19   auto lambda = [=, &y] () -> T {
     20     T i = x;
     21     return i + y;
     22   };
     23 
     24   return lambda();
     25 }
     26 
     27 struct X {
     28   X(const X&);
     29 };
     30 
     31 X operator+(X, X);
     32 X operator-(X, X);
     33 
     34 template int captures(int, int);
     35 template X captures(X, X);
     36 
     37 template<typename T>
     38 int infer_result(T x, T y) {
     39   auto lambda = [=](bool b) { return x + y; };
     40   return lambda(true); // expected-error{{no viable conversion from 'X' to 'int'}}
     41 }
     42 
     43 template int infer_result(int, int);
     44 template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result<X>' requested here}}
     45 
     46 // Make sure that lambda's operator() can be used from templates.
     47 template<typename F>
     48 void accept_lambda(F f) {
     49   f(1);
     50 }
     51 
     52 template<typename T>
     53 void pass_lambda(T x) {
     54   accept_lambda([&x](T y) { return x + y; });
     55 }
     56 
     57 template void pass_lambda(int);
     58 
     59 namespace std {
     60   class type_info;
     61 }
     62 
     63 namespace p2 {
     64   struct P {
     65     virtual ~P();
     66   };
     67 
     68   template<typename T>
     69   struct Boom {
     70     Boom(const Boom&) {
     71       T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \
     72       // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
     73     }
     74     void tickle() const;
     75   };
     76 
     77   template<typename R, typename T>
     78   void odr_used(R &r, Boom<T> boom) {
     79     const std::type_info &ti
     80       = typeid([=,&r] () -> R& { // expected-error{{lambda expression in an unevaluated operand}}
     81           boom.tickle(); // expected-note{{in instantiation of member function}}
     82           return r;
     83         }());
     84   }
     85 
     86   template void odr_used(int&, Boom<int>); // expected-note{{in instantiation of function template specialization}}
     87 
     88   template<typename R, typename T>
     89   void odr_used2(R &r, Boom<T> boom) {
     90     const std::type_info &ti
     91       = typeid([=,&r] () -> R& {
     92           boom.tickle(); // expected-note{{in instantiation of member function}}
     93           return r;
     94         }());
     95   }
     96 
     97   template void odr_used2(P&, Boom<float>);
     98 }
     99 
    100 namespace p5 {
    101   struct NonConstCopy {
    102     NonConstCopy(const NonConstCopy&) = delete;
    103     NonConstCopy(NonConstCopy&);
    104   };
    105 
    106   template<typename T>
    107   void double_capture(T &nc) {
    108     [=] () mutable {
    109       [=] () mutable {
    110         T nc2(nc);
    111       }();
    112     }();
    113   }
    114 
    115   template void double_capture(NonConstCopy&);
    116 }
    117 
    118 namespace NonLocalLambdaInstantation {
    119   template<typename T>
    120   struct X {
    121     static int value;
    122   };
    123 
    124   template<typename T>
    125   int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}
    126 
    127   template int X<int>::value;
    128   template int X<float>::value;
    129   template int X<int*>::value; // expected-note{{in instantiation of static data member }}
    130 
    131   template<typename T>
    132   void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \
    133      // expected-note{{passing argument to parameter 'x' here}}
    134 
    135   void call_defaults() {
    136     defaults<int>();
    137     defaults<float>();
    138     defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}
    139   }
    140 
    141   template<typename T>
    142   struct X2 {
    143     int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
    144   };
    145 
    146   X2<int> x2i;
    147   X2<float> x2f;
    148   X2<int*> x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2<int *>' requested here}}
    149 }
    150