| Douglas Gregor | 0c46b2b | 2012-02-13 22:00:16 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify | 
|  | 2 |  | 
|  | 3 | template<typename T> | 
|  | 4 | void test_attributes() { | 
| Douglas Gregor | cf11eb7 | 2012-02-15 16:20:15 +0000 | [diff] [blame] | 5 | auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}} | 
| Douglas Gregor | 0c46b2b | 2012-02-13 22:00:16 +0000 | [diff] [blame] | 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 |  | 
| Douglas Gregor | b432823 | 2012-02-14 00:00:48 +0000 | [diff] [blame] | 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 | } | 
| Douglas Gregor | a86bc00 | 2012-02-16 21:36:18 +0000 | [diff] [blame] | 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 | } |