10c46b2b7SDouglas Gregor // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify
20c46b2b7SDouglas Gregor 
30c46b2b7SDouglas Gregor template<typename T>
test_attributes()40c46b2b7SDouglas Gregor void test_attributes() {
510876ef5SRichard Smith   // FIXME: GCC accepts [[gnu::noreturn]] here.
610876ef5SRichard Smith   auto nrl = []() [[gnu::noreturn]] {}; // expected-warning{{attribute 'noreturn' ignored}}
70c46b2b7SDouglas Gregor }
80c46b2b7SDouglas Gregor 
910876ef5SRichard Smith template void test_attributes<int>();
100c46b2b7SDouglas Gregor 
110c46b2b7SDouglas Gregor template<typename T>
call_with_zero()120c46b2b7SDouglas Gregor void call_with_zero() {
130c46b2b7SDouglas Gregor   [](T *ptr) -> T& { return *ptr; }(0);
140c46b2b7SDouglas Gregor }
150c46b2b7SDouglas Gregor 
160c46b2b7SDouglas Gregor template void call_with_zero<int>();
170c46b2b7SDouglas Gregor 
180c46b2b7SDouglas Gregor template<typename T>
captures(T x,T y)190c46b2b7SDouglas Gregor T captures(T x, T y) {
200c46b2b7SDouglas Gregor   auto lambda = [=, &y] () -> T {
210c46b2b7SDouglas Gregor     T i = x;
220c46b2b7SDouglas Gregor     return i + y;
230c46b2b7SDouglas Gregor   };
240c46b2b7SDouglas Gregor 
250c46b2b7SDouglas Gregor   return lambda();
260c46b2b7SDouglas Gregor }
270c46b2b7SDouglas Gregor 
280c46b2b7SDouglas Gregor struct X {
290c46b2b7SDouglas Gregor   X(const X&);
300c46b2b7SDouglas Gregor };
310c46b2b7SDouglas Gregor 
320c46b2b7SDouglas Gregor X operator+(X, X);
330c46b2b7SDouglas Gregor X operator-(X, X);
340c46b2b7SDouglas Gregor 
350c46b2b7SDouglas Gregor template int captures(int, int);
360c46b2b7SDouglas Gregor template X captures(X, X);
370c46b2b7SDouglas Gregor 
380c46b2b7SDouglas Gregor template<typename T>
infer_result(T x,T y)390c46b2b7SDouglas Gregor int infer_result(T x, T y) {
400c46b2b7SDouglas Gregor   auto lambda = [=](bool b) { return x + y; };
4108426e20SNick Lewycky   return lambda(true); // expected-error{{no viable conversion from returned value of type 'X' to function return type 'int'}}
420c46b2b7SDouglas Gregor }
430c46b2b7SDouglas Gregor 
440c46b2b7SDouglas Gregor template int infer_result(int, int);
450c46b2b7SDouglas Gregor template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result<X>' requested here}}
460c46b2b7SDouglas Gregor 
47b4328233SDouglas Gregor // Make sure that lambda's operator() can be used from templates.
48b4328233SDouglas Gregor template<typename F>
accept_lambda(F f)49b4328233SDouglas Gregor void accept_lambda(F f) {
50b4328233SDouglas Gregor   f(1);
51b4328233SDouglas Gregor }
52b4328233SDouglas Gregor 
53b4328233SDouglas Gregor template<typename T>
pass_lambda(T x)54b4328233SDouglas Gregor void pass_lambda(T x) {
55b4328233SDouglas Gregor   accept_lambda([&x](T y) { return x + y; });
56b4328233SDouglas Gregor }
57b4328233SDouglas Gregor 
58b4328233SDouglas Gregor template void pass_lambda(int);
59b4328233SDouglas Gregor 
60b4328233SDouglas Gregor namespace std {
61b4328233SDouglas Gregor   class type_info;
62b4328233SDouglas Gregor }
63b4328233SDouglas Gregor 
64b4328233SDouglas Gregor namespace p2 {
65b4328233SDouglas Gregor   struct P {
66b4328233SDouglas Gregor     virtual ~P();
67b4328233SDouglas Gregor   };
68b4328233SDouglas Gregor 
69b4328233SDouglas Gregor   template<typename T>
70b4328233SDouglas Gregor   struct Boom {
Boomp2::Boom71b4328233SDouglas Gregor     Boom(const Boom&) {
72c38498f0SRichard Smith       T* x = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}
73b4328233SDouglas Gregor     }
74b4328233SDouglas Gregor     void tickle() const;
75b4328233SDouglas Gregor   };
76b4328233SDouglas Gregor 
77b4328233SDouglas Gregor   template<typename R, typename T>
odr_used(R & r,Boom<T> boom)78b4328233SDouglas Gregor   void odr_used(R &r, Boom<T> boom) {
79b4328233SDouglas Gregor     const std::type_info &ti
80b4328233SDouglas Gregor       = typeid([=,&r] () -> R& { // expected-error{{lambda expression in an unevaluated operand}}
81c38498f0SRichard Smith           boom.tickle();
82b4328233SDouglas Gregor           return r;
83b4328233SDouglas Gregor         }());
84b4328233SDouglas Gregor   }
85b4328233SDouglas Gregor 
86b4328233SDouglas Gregor   template void odr_used(int&, Boom<int>); // expected-note{{in instantiation of function template specialization}}
87b4328233SDouglas Gregor 
88b4328233SDouglas Gregor   template<typename R, typename T>
odr_used2(R & r,Boom<T> boom)89b4328233SDouglas Gregor   void odr_used2(R &r, Boom<T> boom) {
90b4328233SDouglas Gregor     const std::type_info &ti
9135d303adSVedant Kumar       = typeid([=,&r] () -> R& { // expected-note{{in instantiation of member function 'p2::Boom<float>::Boom' requested here}}
9235d303adSVedant Kumar           boom.tickle();
93b4328233SDouglas Gregor           return r;
94b4328233SDouglas Gregor         }());
95b4328233SDouglas Gregor   }
96b4328233SDouglas Gregor 
97b4328233SDouglas Gregor   template void odr_used2(P&, Boom<float>);
98b4328233SDouglas Gregor }
99b4328233SDouglas Gregor 
100b4328233SDouglas Gregor namespace p5 {
101b4328233SDouglas Gregor   struct NonConstCopy {
102b4328233SDouglas Gregor     NonConstCopy(const NonConstCopy&) = delete;
103b4328233SDouglas Gregor     NonConstCopy(NonConstCopy&);
104b4328233SDouglas Gregor   };
105b4328233SDouglas Gregor 
106b4328233SDouglas Gregor   template<typename T>
double_capture(T & nc)107b4328233SDouglas Gregor   void double_capture(T &nc) {
108b4328233SDouglas Gregor     [=] () mutable {
109b4328233SDouglas Gregor       [=] () mutable {
110b4328233SDouglas Gregor         T nc2(nc);
111b4328233SDouglas Gregor       }();
112b4328233SDouglas Gregor     }();
113b4328233SDouglas Gregor   }
114b4328233SDouglas Gregor 
115b4328233SDouglas Gregor   template void double_capture(NonConstCopy&);
116b4328233SDouglas Gregor }
117a86bc00dSDouglas Gregor 
118*e181a6aeSArthur O'Dwyer namespace NonLocalLambdaInstantiation {
119a86bc00dSDouglas Gregor   template<typename T>
120a86bc00dSDouglas Gregor   struct X {
121a86bc00dSDouglas Gregor     static int value;
122a86bc00dSDouglas Gregor   };
123a86bc00dSDouglas Gregor 
124a86bc00dSDouglas Gregor   template<typename T>
__anonca379c690a02null125a86bc00dSDouglas Gregor   int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}
126a86bc00dSDouglas Gregor 
127a86bc00dSDouglas Gregor   template int X<int>::value;
128a86bc00dSDouglas Gregor   template int X<float>::value;
129a86bc00dSDouglas Gregor   template int X<int*>::value; // expected-note{{in instantiation of static data member }}
130a86bc00dSDouglas Gregor 
131a86bc00dSDouglas Gregor   template<typename T>
__anonca379c690b02null132a86bc00dSDouglas Gregor   void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \
133a86bc00dSDouglas Gregor      // expected-note{{passing argument to parameter 'x' here}}
134a86bc00dSDouglas Gregor 
call_defaults()135a86bc00dSDouglas Gregor   void call_defaults() {
136a86bc00dSDouglas Gregor     defaults<int>();
137a86bc00dSDouglas Gregor     defaults<float>();
138a86bc00dSDouglas Gregor     defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}
139a86bc00dSDouglas Gregor   }
140a86bc00dSDouglas Gregor 
141a86bc00dSDouglas Gregor   template<typename T>
142*e181a6aeSArthur O'Dwyer   struct X2 { // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantiation::X2<int *>::x'}}
__anonca379c690c02NonLocalLambdaInstantiation::X2143a86bc00dSDouglas Gregor     int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
144a86bc00dSDouglas Gregor   };
145a86bc00dSDouglas Gregor 
146a86bc00dSDouglas Gregor   X2<int> x2i;
147a86bc00dSDouglas Gregor   X2<float> x2f;
1485159bbadSRichard Smith   X2<int*> x2ip; // expected-note {{in evaluation of exception spec}}
149a86bc00dSDouglas Gregor }
150