// RUN: %clang_cc1 -std=c++11 -verify %s template struct X {}; template struct P {}; namespace Nested { template int f1(X... a); // expected-note +{{packs of different lengths for parameter 'T'}} template int f2(P, T> ...a); // expected-note +{{packs of different lengths for parameter 'T'}} int a1 = f1(X(), X()); int a2 = f1(X()); int a3 = f1(X(), X()); // expected-error {{no matching}} int a4 = f1(X(), X()); // expected-error {{no matching}} int a5 = f1(X(), X()); // expected-error {{no matching}} int a6 = f1(X(), X(), X()); // expected-error {{no matching}} int b1 = f2(P, int>(), P, double>()); int b2 = f2(P, int>(), P, double>(), P, char>()); // expected-error {{no matching}} } namespace PR14841 { template struct A {}; template void f(A); // expected-note {{substitution failure [with Ts = ]: too many template arg}} void g(A a) { f(a); f(a); f(a); f(a); // expected-error {{no matching function}} } } namespace RetainExprPacks { int f(int a, int b, int c); template struct X {}; template int g(X, decltype(f(Ts()...))); int n = g(X(), 0); } namespace PR14615 { namespace comment0 { template struct X {}; template struct X { typedef int type; struct valid {}; }; template , typename = typename T::valid> typename T::type check(int); int i = check(1); } namespace comment2 { template struct X; template ::type I = 0> char check(B...); // expected-note {{undefined template 'PR14615::comment2::X'}} void f() { check(1, 2); } // expected-error {{no matching function}} } namespace comment3 { template struct X; template ::type I = (typename X::type)0> char check(B...); // expected-note {{undefined template 'PR14615::comment3::X'}} void f() { check(1, 2); } // expected-error {{no matching function}} } } namespace fully_expanded_packs { template struct A { template static constexpr int f() { // expected-note@-1 1+{{deduced too few arguments for expanded pack 'X'}} // expected-note@-2 1+{{too many template arguments}} return (X + ... + 0); // expected-warning {{extension}} } template static constexpr int g() { // expected-note@-1 1+{{deduced too few arguments for expanded pack 'X'}} // expected-note@-2 1+{{couldn't infer template argument 'Y'}} // expected-note@-3 1+{{too many template arguments}} return (X + ... + (1000 * Y)); // expected-warning {{extension}} } template static constexpr int h() { // expected-note@-1 1+{{deduced too few arguments for expanded pack 'X'}} // expected-note@-2 1+{{couldn't infer template argument 'Y'}} // expected-note@-3 1+{{deduced too few arguments for expanded pack 'Z'}} // expected-note@-4 1+{{too many template arguments}} return (X + ... + (1000 * Y)) + 1000000 * (Z + ... + 0); // expected-warning 2{{extension}} } template static constexpr int i() { return (X + ... + 0) + 1000 * (Z + ... + 0); // expected-warning 2{{extension}} } template static constexpr int j() { return (X + ... + (1000 * Y)) + 1000000 * (Z + ... + 0); // expected-warning 2{{extension}} } }; void check_invalid_calls() { A::f(); // expected-error {{no matching function}} A::f<>(); // expected-error {{no matching function}} A::f<0>(); // expected-error {{no matching function}} A::g(); // expected-error {{no matching function}} A::g<>(); // expected-error {{no matching function}} A::g<0>(); // expected-error {{no matching function}} A::g<0, 0>(); // expected-error {{no matching function}} A<>::f<0>(); // expected-error {{no matching function}} A<>::g(); // expected-error {{no matching function}} A<>::g<>(); // expected-error {{no matching function}} A<>::g<0, 0>(); // expected-error {{no matching function}} A<>::h<>(); // expected-error {{no matching function}} A::h<>(); // expected-error {{no matching function}} A::h<0, 0>(); // expected-error {{no matching function}} A<>::h<0, 0>(); // expected-error {{no matching function}} } static_assert(A<>::f() == 0, ""); static_assert(A::f<1>() == 1, ""); static_assert(A<>::g<1>() == 1000, ""); static_assert(A::g<1, 2>() == 2001, ""); static_assert(A<>::h<1>() == 1000, ""); static_assert(A::h<1, 2, 3>() == 3002001, ""); static_assert(A::h<1, 20, 3, 4, 50>() == 54003021, ""); static_assert(A<>::i<1>() == 1000, ""); static_assert(A::i<1>() == 1, ""); static_assert(A<>::j<1, 2, 30>() == 32001000, ""); static_assert(A::j<1, 2, 3, 40>() == 43002001, ""); } namespace partial_full_mix { template struct pair {}; template struct tuple {}; template struct A { template static pair, tuple> f(pair ...p); // expected-note@-1 {{[with U = ]: pack expansion contains parameter pack 'U' that has a different length (2 vs. 3) from outer parameter packs}} // expected-note@-2 {{[with U = ]: pack expansion contains parameter pack 'U' that has a different length (at least 3 vs. 2) from outer parameter packs}} template static pair, tuple> g(pair ...p, ...); // expected-note@-1 {{[with U = ]: pack expansion contains parameter pack 'U' that has a different length (2 vs. 3) from outer parameter packs}} template static tuple h(tuple..., pair>); // expected-note@-1 {{[with U = ]: pack expansion contains parameter pack 'U' that has a different length (2 vs. 1) from outer parameter packs}} }; pair, tuple> k1 = A().f(pair(), pair()); pair, tuple> k2 = A().f(pair(), pair(), pair()); // expected-error {{no match}} pair, tuple> k3 = A().f(pair(), pair()); // expected-error {{no match}} // FIXME: We should accept this by treating the pack 'p' as having a fixed length of 2 here. pair, tuple> k4 = A().g(pair(), pair(), pair()); // expected-error {{no match}} // FIXME: We should accept this by treating the pack of pairs as having a fixed length of 2 here. tuple k5 = A::h(tuple, pair, pair>()); // expected-error {{no match}} } namespace substitution_vs_function_deduction { template struct A { template void f(void(*...)(T, U)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} template void g(void...(T, U)); // expected-note {{could not match 'void (T, U)' against 'void (*)(int, int)'}} }; void f(int, int) { A().f(f); // FIXME: We fail to decay the parameter to a pointer type. A().g(f); // expected-error {{no match}} } } namespace Nested_Explicit_Specialization { template struct Outer { template struct Inner; template <> struct Inner<0> { template void Test(Args...) {} }; }; void Run() { Outer::Inner<0>().Test(1,1); } }