r209054 - Correct incoherent function versus function template partial ordering for conversion operators (the comparison could claim that two conversion operators are both better than each other). Actually implement DR495, rather than passing its test by chance because the declarations happened to be in the "lucky" order.

Richard Smith richard-llvm at metafoo.co.uk
Fri May 16 18:58:45 PDT 2014


Author: rsmith
Date: Fri May 16 20:58:45 2014
New Revision: 209054

URL: http://llvm.org/viewvc/llvm-project?rev=209054&view=rev
Log:
Correct incoherent function versus function template partial ordering for conversion operators (the comparison could claim that two conversion operators are both better than each other). Actually implement DR495, rather than passing its test by chance because the declarations happened to be in the "lucky" order.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/drs/dr4xx.cpp
    cfe/trunk/test/SemaCXX/overloaded-operator.cpp
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=209054&r1=209053&r2=209054&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri May 16 20:58:45 2014
@@ -8237,29 +8237,6 @@ isBetterOverloadCandidate(Sema &S,
   if (HasBetterConversion)
     return true;
 
-  //     - F1 is a non-template function and F2 is a function template
-  //       specialization, or, if not that,
-  if ((!Cand1.Function || !Cand1.Function->getPrimaryTemplate()) &&
-      Cand2.Function && Cand2.Function->getPrimaryTemplate())
-    return true;
-
-  //   -- F1 and F2 are function template specializations, and the function
-  //      template for F1 is more specialized than the template for F2
-  //      according to the partial ordering rules described in 14.5.5.2, or,
-  //      if not that,
-  if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
-      Cand2.Function && Cand2.Function->getPrimaryTemplate()) {
-    if (FunctionTemplateDecl *BetterTemplate
-          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
-                                         Cand2.Function->getPrimaryTemplate(),
-                                         Loc,
-                       isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
-                                                             : TPOC_Call,
-                                         Cand1.ExplicitCallArguments,
-                                         Cand2.ExplicitCallArguments))
-      return BetterTemplate == Cand1.Function->getPrimaryTemplate();
-  }
-
   //   -- the context is an initialization by user-defined conversion
   //      (see 8.5, 13.3.1.5) and the standard conversion sequence
   //      from the return type of F1 to the destination type (i.e.,
@@ -8277,7 +8254,7 @@ isBetterOverloadCandidate(Sema &S,
       = compareConversionFunctions(S, Cand1.Function, Cand2.Function);
     if (FuncResult != ImplicitConversionSequence::Indistinguishable)
       return FuncResult;
-          
+
     switch (CompareStandardConversionSequences(S,
                                                Cand1.FinalConversion,
                                                Cand2.FinalConversion)) {
@@ -8293,6 +8270,35 @@ isBetterOverloadCandidate(Sema &S,
       // Do nothing
       break;
     }
+
+    // FIXME: Compare kind of reference binding if conversion functions
+    // convert to a reference type used in direct reference binding, per
+    // C++14 [over.match.best]p1 section 2 bullet 3.
+  }
+
+  //    -- F1 is a non-template function and F2 is a function template
+  //       specialization, or, if not that,
+  bool Cand1IsSpecialization = Cand1.Function &&
+                               Cand1.Function->getPrimaryTemplate();
+  bool Cand2IsSpecialization = Cand2.Function &&
+                               Cand2.Function->getPrimaryTemplate();
+  if (Cand1IsSpecialization != Cand2IsSpecialization)
+    return Cand2IsSpecialization;
+
+  //   -- F1 and F2 are function template specializations, and the function
+  //      template for F1 is more specialized than the template for F2
+  //      according to the partial ordering rules described in 14.5.5.2, or,
+  //      if not that,
+  if (Cand1IsSpecialization && Cand2IsSpecialization) {
+    if (FunctionTemplateDecl *BetterTemplate
+          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+                                         Cand2.Function->getPrimaryTemplate(),
+                                         Loc,
+                       isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
+                                                             : TPOC_Call,
+                                         Cand1.ExplicitCallArguments,
+                                         Cand2.ExplicitCallArguments))
+      return BetterTemplate == Cand1.Function->getPrimaryTemplate();
   }
 
   // Check for enable_if value-based overload resolution.

Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=209054&r1=209053&r2=209054&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr4xx.cpp Fri May 16 20:58:45 2014
@@ -1165,7 +1165,7 @@ namespace dr494 { // dr494: dup 372
   };
 }
 
-namespace dr495 { // dr495: yes
+namespace dr495 { // dr495: 3.5
   template<typename T>
   struct S {
     operator int() { return T::error; }
@@ -1173,6 +1173,14 @@ namespace dr495 { // dr495: yes
   };
   S<int> s;
   long n = s;
+
+  template<typename T>
+  struct S2 {
+    template<typename U> operator U();
+    operator int() { return T::error; }
+  };
+  S2<int> s2;
+  long n2 = s2;
 }
 
 namespace dr496 { // dr496: no

Modified: cfe/trunk/test/SemaCXX/overloaded-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator.cpp?rev=209054&r1=209053&r2=209054&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-operator.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-operator.cpp Fri May 16 20:58:45 2014
@@ -507,3 +507,15 @@ namespace PR14995 {
   // expected-note at -12 {{candidate template ignored: substitution failure}}
 } // namespace PR14995
 
+namespace ConversionVersusTemplateOrdering {
+  struct A {
+    operator short() = delete;
+    template <typename T> operator T();
+  } a;
+  struct B {
+    template <typename T> operator T();
+    operator short() = delete;
+  } b;
+  int x = a;
+  int y = b;
+}

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=209054&r1=209053&r2=209054&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri May 16 20:58:45 2014
@@ -3011,7 +3011,7 @@ of class templates</td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#495">495</a></td>
     <td>CD2</td>
     <td>Overload resolution with template and non-template conversion functions</td>
-    <td class="full" align="center">Yes</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="496">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496">496</a></td>





More information about the cfe-commits mailing list