| 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y |
| 2 | |
| 3 | namespace test_factorial { |
| 4 | |
| 5 | auto Fact = [](auto Self, unsigned n) -> unsigned { |
| 6 | return !n ? 1 : Self(Self, n - 1) * n; |
| 7 | }; |
| 8 | |
| 9 | auto six = Fact(Fact, 3); |
| 10 | |
| 11 | } |
| 12 | |
| 13 | namespace overload_generic_lambda { |
| 14 | template <class F1, class F2> struct overload : F1, F2 { |
| 15 | using F1::operator(); |
| 16 | using F2::operator(); |
| 17 | overload(F1 f1, F2 f2) : F1(f1), F2(f2) { } |
| 18 | }; |
| 19 | |
| 20 | auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned { |
| 21 | return 1 + Self(Self, rest...); |
| 22 | }; |
| 23 | auto Base = [](auto Self, auto h) -> unsigned { |
| 24 | return 1; |
| 25 | }; |
| 26 | overload<decltype(Base), decltype(NumParams)> O(Base, NumParams); |
| 27 | int num_params = O(O, 5, 3, "abc", 3.14, 'a'); |
| 28 | } |
| 29 | |
| 30 | |
| 31 | namespace overload_generic_lambda_return_type_deduction { |
| 32 | template <class F1, class F2> struct overload : F1, F2 { |
| 33 | using F1::operator(); |
| 34 | using F2::operator(); |
| 35 | overload(F1 f1, F2 f2) : F1(f1), F2(f2) { } |
| 36 | }; |
| 37 | |
| 38 | auto NumParams = [](auto Self, auto h, auto ... rest) { |
| 39 | return 1 + Self(Self, rest...); |
| 40 | }; |
| 41 | auto Base = [](auto Self, auto h) { |
| 42 | return 1; |
| 43 | }; |
| 44 | overload<decltype(Base), decltype(NumParams)> O(Base, NumParams); |
| 45 | int num_params = O(O, 5, 3, "abc", 3.14, 'a'); |
| 46 | } |
| 47 | |
| 48 | namespace test_standard_p5 { |
| 49 | // FIXME: This test should eventually compile without an explicit trailing return type |
| 50 | auto glambda = [](auto a, auto&& b) ->bool { return a < b; }; |
| 51 | bool b = glambda(3, 3.14); // OK |
| 52 | |
| 53 | } |
| 54 | namespace test_deduction_failure { |
| 55 | int test() { |
| 56 | auto g = [](auto *a) { //expected-note{{candidate template ignored}} |
| 57 | return a; |
| 58 | }; |
| 59 | struct X { }; |
| 60 | X *x; |
| 61 | g(x); |
| 62 | g(3); //expected-error{{no matching function}} |
| 63 | return 0; |
| 64 | } |
| 65 | |
| 66 | } |
| 67 | |
| 68 | namespace test_instantiation_or_sfinae_failure { |
| 69 | int test2() { |
| 70 | { |
| 71 | auto L = [](auto *a) { |
| 72 | return (*a)(a); }; //expected-error{{called object type 'double' is not a function}} |
| 73 | double d; |
| 74 | L(&d); //expected-note{{in instantiation of}} |
| 75 | auto M = [](auto b) { return b; }; |
| 76 | L(&M); // ok |
| 77 | } |
| 78 | { |
| 79 | auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}} |
| 80 | return (*a)(a); }; |
| 81 | double d; |
| 82 | L(&d); //expected-error{{no matching function for call}} |
| 83 | auto M = [](auto b) { return b; }; |
| 84 | L(&M); //expected-error{{no matching function for call}} |
| 85 | |
| 86 | } |
| 87 | return 0; |
| 88 | } |
| 89 | |
| 90 | |
| 91 | } |
| 92 | |
| 93 | namespace test_misc { |
| 94 | auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}} |
| 95 | -> int { return a + b; }; |
| 96 | |
| 97 | void test() { |
| 98 | struct X { }; |
| 99 | GL(3, X{}); //expected-error{{no matching function}} |
| 100 | } |
| 101 | |
| 102 | void test2() { |
| 103 | auto l = [](auto *a) -> int { |
| 104 | (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}} |
| 105 | l(&l); |
| 106 | double d; |
| 107 | l(&d); //expected-note{{in instantiation of}} |
| 108 | } |
| 109 | |
| 110 | } |
| 111 | |
| 112 | namespace nested_lambdas { |
| 113 | int test() { |
| 114 | auto L = [](auto a) { |
| 115 | return [=](auto b) { |
| 116 | return a + b; |
| 117 | }; |
| 118 | }; |
| 119 | } |
| 120 | auto get_lambda() { |
| 121 | return [](auto a) { |
| 122 | return a; |
| 123 | }; |
| 124 | }; |
| 125 | |
| 126 | int test2() { |
| 127 | auto L = get_lambda(); |
| 128 | L(3); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | |