1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify |
2 | |
3 | template<typename T> |
4 | void test_attributes() { |
5 | // FIXME: GCC accepts [[gnu::noreturn]] here. |
6 | auto nrl = []() [[gnu::noreturn]] {}; // expected-warning{{attribute 'noreturn' ignored}} |
7 | } |
8 | |
9 | template void test_attributes<int>(); |
10 | |
11 | template<typename T> |
12 | void call_with_zero() { |
13 | [](T *ptr) -> T& { return *ptr; }(0); |
14 | } |
15 | |
16 | template void call_with_zero<int>(); |
17 | |
18 | template<typename T> |
19 | T captures(T x, T y) { |
20 | auto lambda = [=, &y] () -> T { |
21 | T i = x; |
22 | return i + y; |
23 | }; |
24 | |
25 | return lambda(); |
26 | } |
27 | |
28 | struct X { |
29 | X(const X&); |
30 | }; |
31 | |
32 | X operator+(X, X); |
33 | X operator-(X, X); |
34 | |
35 | template int captures(int, int); |
36 | template X captures(X, X); |
37 | |
38 | template<typename T> |
39 | int infer_result(T x, T y) { |
40 | auto lambda = [=](bool b) { return x + y; }; |
41 | return lambda(true); // expected-error{{no viable conversion from returned value of type 'X' to function return type 'int'}} |
42 | } |
43 | |
44 | template int infer_result(int, int); |
45 | template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result<X>' requested here}} |
46 | |
47 | // Make sure that lambda's operator() can be used from templates. |
48 | template<typename F> |
49 | void accept_lambda(F f) { |
50 | f(1); |
51 | } |
52 | |
53 | template<typename T> |
54 | void pass_lambda(T x) { |
55 | accept_lambda([&x](T y) { return x + y; }); |
56 | } |
57 | |
58 | template void pass_lambda(int); |
59 | |
60 | namespace std { |
61 | class type_info; |
62 | } |
63 | |
64 | namespace p2 { |
65 | struct P { |
66 | virtual ~P(); |
67 | }; |
68 | |
69 | template<typename T> |
70 | struct Boom { |
71 | Boom(const Boom&) { |
72 | T* x = 1; // 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(); |
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& { // expected-note{{in instantiation of member function 'p2::Boom<float>::Boom' requested here}} |
92 | boom.tickle(); |
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 { // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantation::X2<int *>::x'}} |
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 evaluation of exception spec}} |
149 | } |
150 | |