blob: 49b9c66b1ce547132a3feb721b5dfaab90aa939d [file] [log] [blame]
Douglas Gregor0c46b2b2012-02-13 22:00:16 +00001// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify
2
3template<typename T>
4void test_attributes() {
Douglas Gregorcf11eb72012-02-15 16:20:15 +00005 auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}}
Douglas Gregor0c46b2b2012-02-13 22:00:16 +00006}
7
8template void test_attributes<int>(); // expected-note{{in instantiation of function}}
9
10template<typename T>
11void call_with_zero() {
12 [](T *ptr) -> T& { return *ptr; }(0);
13}
14
15template void call_with_zero<int>();
16
17template<typename T>
18T 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
27struct X {
28 X(const X&);
29};
30
31X operator+(X, X);
32X operator-(X, X);
33
34template int captures(int, int);
35template X captures(X, X);
36
37template<typename T>
38int 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
43template int infer_result(int, int);
44template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result<X>' requested here}}
45
Douglas Gregorb4328232012-02-14 00:00:48 +000046// Make sure that lambda's operator() can be used from templates.
47template<typename F>
48void accept_lambda(F f) {
49 f(1);
50}
51
52template<typename T>
53void pass_lambda(T x) {
54 accept_lambda([&x](T y) { return x + y; });
55}
56
57template void pass_lambda(int);
58
59namespace std {
60 class type_info;
61}
62
63namespace 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
100namespace 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 Gregora86bc002012-02-16 21:36:18 +0000117
118namespace 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}