1 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2b %s 2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx14_20 %s 3 // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify=expected,cxx14_20 %s 4 5 int a; 6 int &b = [] (int &r) -> decltype(auto) { return r; } (a); 7 int &c = [] (int &r) -> decltype(auto) { return (r); } (a); 8 int &d = [] (int &r) -> auto & { return r; } (a); 9 int &e = [] (int &r) -> auto { return r; } (a); // expected-error {{cannot bind to a temporary}} 10 int &f = [] (int r) -> decltype(auto) { return r; } (a); // expected-error {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} 11 int &g = [] (int r) -> decltype(auto) { return (r); } (a); // expected-warning {{reference to stack}} 12 // cxx2b-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} 13 14 int test_explicit_auto_return() 15 { 16 struct X {}; 17 auto L = [](auto F, auto a) { return F(a); }; 18 auto M = [](auto a) -> auto { return a; }; // OK 19 auto MRef = [](auto b) -> auto & { return b; }; //cxx14_20-warning{{reference to stack}} 20 // cxx2b-error@-1 {{non-const lvalue reference to type 'X' cannot bind to a temporary of type 'X'}} 21 auto MPtr = [](auto c) -> auto* { return &c; }; //expected-warning{{address of stack}} 22 auto MDeclType = [](auto&& d) -> decltype(auto) { return static_cast<decltype(d)>(d); }; //OK 23 M(3); 24 25 auto &&x = MDeclType(X{}); 26 auto &&x1 = M(X{}); 27 auto &&x2 = MRef(X{});//expected-note{{in instantiation of}} 28 auto &&x3 = MPtr(X{}); //expected-note{{in instantiation of}} 29 return 0; 30 } 31 32 int test_implicit_auto_return() 33 { 34 { 35 auto M = [](auto a) { return a; }; 36 struct X {}; 37 X x = M(X{}); 38 39 } 40 } 41 42 int test_multiple_returns() { 43 auto M = [](auto a) { 44 bool k; 45 if (k) 46 return a; 47 else 48 return 5; //expected-error{{deduced as 'int' here}} 49 }; 50 M(3); // OK 51 M('a'); //expected-note{{in instantiation of}} 52 return 0; 53 } 54 int test_no_parameter_list() 55 { 56 static int si = 0; 57 auto M = [] { return 5; }; // OK 58 auto M2 = [] -> auto && { return si; }; 59 #if __cplusplus <= 202002L 60 // expected-warning@-2{{is a C++2b extension}} 61 #endif 62 M(); 63 } 64 65 int test_conditional_in_return() { 66 auto Fac = [](auto f, auto n) { 67 return n <= 0 ? n : f(f, n - 1) * n; 68 }; 69 // FIXME: this test causes a recursive limit - need to error more gracefully. 70 //Fac(Fac, 3); 71 72 } 73