[PATCH] D128745: [Sema] fix trailing parameter pack handling for function template partial ordering

Yuanfang Chen via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 28 11:11:26 PDT 2022


ychen created this revision.
ychen added reviewers: rsmith, aaron.ballman.
Herald added a project: All.
ychen requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128745

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/drs/dr6xx.cpp


Index: clang/test/CXX/drs/dr6xx.cpp
===================================================================
--- clang/test/CXX/drs/dr6xx.cpp
+++ clang/test/CXX/drs/dr6xx.cpp
@@ -1086,15 +1086,12 @@
     template <typename T, typename U> struct A {};
     template <typename T, typename U> void f(U, A<U, T> *p = 0); // expected-note {{candidate}}
     template <typename U> int &f(U, A<U, U> *p = 0); // expected-note {{candidate}}
-    template <typename T> void g(T, T = T());
-    template <typename T, typename... U> void g(T, U...); // expected-error 0-1{{C++11}}
+    template <typename T> void g(T, T = T()); // expected-note {{candidate}}
+    template <typename T, typename... U> void g(T, U...); // expected-note {{candidate}} // expected-error 0-1{{C++11}}
     void h() {
       int &r = f<int>(42, (A<int, int> *)0);
       f<int>(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}}
     }
   }
 
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ 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();
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128745.440700.patch
Type: text/x-patch
Size: 2489 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220628/67b621e1/attachment-0001.bin>


More information about the cfe-commits mailing list