]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / CXX / expr / expr.prim / expr.prim.lambda / templates.cpp
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 'X' to '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 'int *' with an rvalue of type 'int'}} \
73       // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
74     }
75     void tickle() const;
76   };
77   
78   template<typename R, typename T>
79   void odr_used(R &r, Boom<T> boom) {
80     const std::type_info &ti
81       = typeid([=,&r] () -> R& { // expected-error{{lambda expression in an unevaluated operand}}
82           boom.tickle(); // expected-note{{in instantiation of member function}}
83           return r; 
84         }()); 
85   }
86
87   template void odr_used(int&, Boom<int>); // expected-note{{in instantiation of function template specialization}}
88
89   template<typename R, typename T>
90   void odr_used2(R &r, Boom<T> boom) {
91     const std::type_info &ti
92       = typeid([=,&r] () -> R& {
93           boom.tickle(); // expected-note{{in instantiation of member function}}
94           return r; 
95         }()); 
96   }
97
98   template void odr_used2(P&, Boom<float>);
99 }
100
101 namespace p5 {
102   struct NonConstCopy {
103     NonConstCopy(const NonConstCopy&) = delete;
104     NonConstCopy(NonConstCopy&);
105   };
106
107   template<typename T>
108   void double_capture(T &nc) {
109     [=] () mutable {
110       [=] () mutable {
111         T nc2(nc);
112       }();
113     }();
114   }
115
116   template void double_capture(NonConstCopy&);
117 }
118
119 namespace NonLocalLambdaInstantation {
120   template<typename T>
121   struct X {
122     static int value;
123   };
124
125   template<typename T>
126   int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}
127
128   template int X<int>::value;
129   template int X<float>::value;
130   template int X<int*>::value; // expected-note{{in instantiation of static data member }}
131
132   template<typename T>
133   void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \
134      // expected-note{{passing argument to parameter 'x' here}}
135
136   void call_defaults() {
137     defaults<int>();
138     defaults<float>();
139     defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}
140   }
141
142   template<typename T>
143   struct X2 {
144     int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
145   };
146
147   X2<int> x2i;
148   X2<float> x2f;
149   X2<int*> x2ip; // expected-note{{in instantiation of template class 'NonLocalLambdaInstantation::X2<int *>' requested here}}
150 }