diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5181,13 +5181,21 @@ if (!Better1 && !Better2) // Neither is better than the other return JudgeByConstraints(); - // FIXME: This mimics what GCC implements, but doesn't match up with the - // proposed resolution for core issue 692. This area needs to be sorted out, - // but for now we attempt to maintain compatibility. + const unsigned NumParams1 = FT1->getTemplatedDecl()->getNumParams(); + const unsigned NumParams2 = FT2->getTemplatedDecl()->getNumParams(); + + // C++ [temp.deduct.partial]p11: + // ... and if G has a trailing function parameter pack for which F does not + // have a corresponding parameter, and if F does not have a trailing + // function parameter pack, then F is more specialized than G. bool Variadic1 = isVariadicFunctionTemplate(FT1); bool Variadic2 = isVariadicFunctionTemplate(FT2); - if (Variadic1 != Variadic2) - return Variadic1? FT2 : FT1; + if (Variadic1 != Variadic2) { + if (Variadic1 && NumParams1 > NumParams2) + return FT2; + if (Variadic2 && NumParams2 > NumParams1) + return FT1; + } return JudgeByConstraints(); } diff --git a/clang/test/CXX/drs/dr6xx.cpp b/clang/test/CXX/drs/dr6xx.cpp --- a/clang/test/CXX/drs/dr6xx.cpp +++ b/clang/test/CXX/drs/dr6xx.cpp @@ -1086,15 +1086,12 @@ template struct A {}; template void f(U, A *p = 0); // expected-note {{candidate}} template int &f(U, A *p = 0); // expected-note {{candidate}} - template void g(T, T = T()); - template void g(T, U...); // expected-error 0-1{{C++11}} + template void g(T, T = T()); // expected-note {{candidate}} + template void g(T, U...); // expected-note {{candidate}} // expected-error 0-1{{C++11}} void h() { int &r = f(42, (A *)0); f(42); // expected-error {{ambiguous}} - // FIXME: We should reject this due to ambiguity between the pack and the - // default argument. Only parameters with arguments are considered during - // partial ordering of function templates. - g(42); + g(42); // expected-error {{ambiguous}} } }