[PATCH] D121517: Incorrectly accepts overload of (T&, int) vs. (T const&, U) #54347

Ed Catmur via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 12 04:35:37 PST 2022


ecatmur created this revision.
Herald added a project: All.
ecatmur requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

clang correctly rejects as ambiguous:

template<class T> int f(T&, int); // 1
template<class T, class U> int f(T const&, U); // 2
int g(int const& i) { return f(i, 0); }
However if the order of template parameters in (2) is swapped:

template<class T> int f(T&, int); // 1
template<class U, class T> int f(T const&, U); // 2'
int g(int const& i) { return f(i, 0); }
clang incorrectly accepts, calling (1).

All versions tested up to current trunk incorrectly accept; 3.6 and older also incorrectly accept the first case.
gcc correctly rejects both cases since 4.5, incorrectly accepting in earlier versions.
icc 13 onwards correctly rejects.
MSVC correctly rejects (although it has other bugs in this area).

The problem appears to be that DeduceTemplateArgumentsByTypeMatch incorrectly believes that P and A are distinct; P is type-parameter-0-1 whereas A is type-parameter-0-0.

I believe this can be fixed simply by removing the hasSameUnqualifiedType check, since if the types are dissimilar the call would fail later anyway,


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121517

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/overload-call.cpp


Index: clang/test/SemaCXX/overload-call.cpp
===================================================================
--- clang/test/SemaCXX/overload-call.cpp
+++ clang/test/SemaCXX/overload-call.cpp
@@ -688,3 +688,13 @@
     f(pmf);
   }
 }
+
+namespace PR54347 {
+  template<class T> void f(T&, int);
+  template<class U, class T> void f(T const&, U);
+  void g(int const& i) { f(i, 0); } // expected-error {{ambiguous}}
+
+  template<class T> void f(T(&)[5], int);
+  template<class U, class T> void f(T const(&)[5], U);
+  void g(int const(& a)[5]) { f(a, 0); } // expected-error {{ambiguous}}
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1358,7 +1358,7 @@
     if (ARef)
       A = A->getPointeeType();
 
-    if (PRef && ARef && S.Context.hasSameUnqualifiedType(P, A)) {
+    if (PRef && ARef) {
       // C++11 [temp.deduct.partial]p9:
       //   If, for a given type, deduction succeeds in both directions (i.e.,
       //   the types are identical after the transformations above) and both


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121517.414822.patch
Type: text/x-patch
Size: 1162 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220312/2e69dd43/attachment.bin>


More information about the cfe-commits mailing list