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