]> granicus.if.org Git - clang/commitdiff
Correct incoherent function versus function template partial ordering for conversion...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 17 May 2014 01:58:45 +0000 (01:58 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 17 May 2014 01:58:45 +0000 (01:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209054 91177308-0d34-0410-b5e6-96231b3b80d8

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

index df4970ec8e0e5c9125db163ca465043ae87491cb..bc8eb2cf6a4e0b52f27800ae83b25b3a2dc2e803 100644 (file)
@@ -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.
index 03f384aeb9e530c28149893f5cff14e80b115f22..815dbfc0b401059fd264f580af6883899ec15849 100644 (file)
@@ -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
index cd2b2d3e7ae26eb47d44a4769304ae4201002cd0..feb7c716ff00836b15c8d44159f26e28ea261c96 100644 (file)
@@ -507,3 +507,15 @@ namespace PR14995 {
   // expected-note@-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;
+}
index dc6339982c877cce60eef1e312c9343f4d8ed1bb..35e72313676caeb3af490e9f65488b0fb63537d2 100644 (file)
@@ -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>