17c9f3ca2SFaisal Vali // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
22b391ab7SFaisal Vali 
32b391ab7SFaisal Vali namespace test_factorial {
42b391ab7SFaisal Vali 
__anonad8db0ae0102(auto Self, unsigned n) 52b391ab7SFaisal Vali auto Fact = [](auto Self, unsigned n) -> unsigned {
62b391ab7SFaisal Vali     return !n ? 1 : Self(Self, n - 1) * n;
72b391ab7SFaisal Vali };
82b391ab7SFaisal Vali 
92b391ab7SFaisal Vali auto six = Fact(Fact, 3);
102b391ab7SFaisal Vali 
112b391ab7SFaisal Vali }
122b391ab7SFaisal Vali 
132b391ab7SFaisal Vali namespace overload_generic_lambda {
142b391ab7SFaisal Vali   template <class F1, class F2> struct overload : F1, F2 {
152b391ab7SFaisal Vali     using F1::operator();
162b391ab7SFaisal Vali     using F2::operator();
overloadoverload_generic_lambda::overload172b391ab7SFaisal Vali     overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
182b391ab7SFaisal Vali   };
192b391ab7SFaisal Vali 
__anonad8db0ae0202(auto Self, auto h, auto ... rest) 202b391ab7SFaisal Vali   auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {
212b391ab7SFaisal Vali     return 1 + Self(Self, rest...);
222b391ab7SFaisal Vali   };
__anonad8db0ae0302(auto Self, auto h) 232b391ab7SFaisal Vali   auto Base = [](auto Self, auto h) -> unsigned {
242b391ab7SFaisal Vali       return 1;
252b391ab7SFaisal Vali   };
262b391ab7SFaisal Vali   overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
272b391ab7SFaisal Vali   int num_params =  O(O, 5, 3, "abc", 3.14, 'a');
282b391ab7SFaisal Vali }
292b391ab7SFaisal Vali 
302b391ab7SFaisal Vali 
312b391ab7SFaisal Vali namespace overload_generic_lambda_return_type_deduction {
322b391ab7SFaisal Vali   template <class F1, class F2> struct overload : F1, F2 {
332b391ab7SFaisal Vali     using F1::operator();
342b391ab7SFaisal Vali     using F2::operator();
overloadoverload_generic_lambda_return_type_deduction::overload352b391ab7SFaisal Vali     overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
362b391ab7SFaisal Vali   };
372b391ab7SFaisal Vali 
__anonad8db0ae0402(auto Self, auto h, auto ... rest) 382b391ab7SFaisal Vali   auto NumParams = [](auto Self, auto h, auto ... rest) {
392b391ab7SFaisal Vali     return 1 + Self(Self, rest...);
402b391ab7SFaisal Vali   };
__anonad8db0ae0502(auto Self, auto h) 412b391ab7SFaisal Vali   auto Base = [](auto Self, auto h) {
422b391ab7SFaisal Vali       return 1;
432b391ab7SFaisal Vali   };
442b391ab7SFaisal Vali   overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
452b391ab7SFaisal Vali   int num_params =  O(O, 5, 3, "abc", 3.14, 'a');
462b391ab7SFaisal Vali }
472b391ab7SFaisal Vali 
482b391ab7SFaisal Vali namespace test_standard_p5 {
492b391ab7SFaisal Vali // FIXME: This test should eventually compile without an explicit trailing return type
__anonad8db0ae0602(auto a, auto&& b) 502b391ab7SFaisal Vali auto glambda = [](auto a, auto&& b) ->bool { return a < b; };
512b391ab7SFaisal Vali bool b = glambda(3, 3.14); // OK
522b391ab7SFaisal Vali 
532b391ab7SFaisal Vali }
542b391ab7SFaisal Vali namespace test_deduction_failure {
test()552b391ab7SFaisal Vali  int test() {
562b391ab7SFaisal Vali    auto g = [](auto *a) { //expected-note{{candidate template ignored}}
572b391ab7SFaisal Vali     return a;
582b391ab7SFaisal Vali    };
592b391ab7SFaisal Vali    struct X { };
602b391ab7SFaisal Vali    X *x;
612b391ab7SFaisal Vali    g(x);
622b391ab7SFaisal Vali    g(3); //expected-error{{no matching function}}
632b391ab7SFaisal Vali    return 0;
642b391ab7SFaisal Vali  }
652b391ab7SFaisal Vali 
662b391ab7SFaisal Vali }
672b391ab7SFaisal Vali 
682b391ab7SFaisal Vali namespace test_instantiation_or_sfinae_failure {
test2()692b391ab7SFaisal Vali int test2() {
702b391ab7SFaisal Vali   {
712b391ab7SFaisal Vali     auto L = [](auto *a) {
722b391ab7SFaisal Vali                 return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}
732b391ab7SFaisal Vali     double d;
742b391ab7SFaisal Vali     L(&d); //expected-note{{in instantiation of}}
752b391ab7SFaisal Vali     auto M = [](auto b) { return b; };
762b391ab7SFaisal Vali     L(&M); // ok
772b391ab7SFaisal Vali   }
782b391ab7SFaisal Vali   {
792b391ab7SFaisal Vali     auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}
802b391ab7SFaisal Vali                 return (*a)(a); };
812b391ab7SFaisal Vali     double d;
822b391ab7SFaisal Vali     L(&d); //expected-error{{no matching function for call}}
832b391ab7SFaisal Vali     auto M = [](auto b) { return b; };
842b391ab7SFaisal Vali     L(&M); //expected-error{{no matching function for call}}
852b391ab7SFaisal Vali 
862b391ab7SFaisal Vali   }
872b391ab7SFaisal Vali   return 0;
882b391ab7SFaisal Vali }
892b391ab7SFaisal Vali 
902b391ab7SFaisal Vali 
912b391ab7SFaisal Vali }
922b391ab7SFaisal Vali 
932b391ab7SFaisal Vali namespace test_misc {
942b391ab7SFaisal Vali auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}}
__anonad8db0ae0b02(auto a, decltype(a) b) 952b391ab7SFaisal Vali                 -> int { return a + b; };
962b391ab7SFaisal Vali 
test()972b391ab7SFaisal Vali void test() {
982b391ab7SFaisal Vali    struct X { };
992b391ab7SFaisal Vali    GL(3, X{}); //expected-error{{no matching function}}
1002b391ab7SFaisal Vali }
1012b391ab7SFaisal Vali 
test2()1022b391ab7SFaisal Vali void test2() {
1032b391ab7SFaisal Vali   auto l = [](auto *a) -> int {
1042b391ab7SFaisal Vali               (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}
1052b391ab7SFaisal Vali   l(&l);
1062b391ab7SFaisal Vali   double d;
1072b391ab7SFaisal Vali   l(&d); //expected-note{{in instantiation of}}
1082b391ab7SFaisal Vali }
1092b391ab7SFaisal Vali 
1102b391ab7SFaisal Vali }
1112b391ab7SFaisal Vali 
1122b391ab7SFaisal Vali namespace nested_lambdas {
test()1132b391ab7SFaisal Vali   int test() {
1142b391ab7SFaisal Vali     auto L = [](auto a) {
115*a17d19fbSFaisal Vali                  return [=](auto b) {
1162b391ab7SFaisal Vali                            return a + b;
1172b391ab7SFaisal Vali                         };
1182b391ab7SFaisal Vali               };
1192b391ab7SFaisal Vali   }
get_lambda()1202b391ab7SFaisal Vali   auto get_lambda() {
1212b391ab7SFaisal Vali     return [](auto a) {
1222b391ab7SFaisal Vali       return a;
1232b391ab7SFaisal Vali     };
1242b391ab7SFaisal Vali   };
1252b391ab7SFaisal Vali 
test2()1262b391ab7SFaisal Vali   int test2() {
1272b391ab7SFaisal Vali     auto L = get_lambda();
1282b391ab7SFaisal Vali     L(3);
1292b391ab7SFaisal Vali   }
1302b391ab7SFaisal Vali }
1312b391ab7SFaisal Vali 
132