r317066 - [c++17] Refine resolution of constructor / conversion function disambiguation.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 31 18:37:11 PDT 2017


Author: rsmith
Date: Tue Oct 31 18:37:11 2017
New Revision: 317066

URL: http://llvm.org/viewvc/llvm-project?rev=317066&view=rev
Log:
[c++17] Refine resolution of constructor / conversion function disambiguation.

Given a choice between a constructor call and a conversion function in C++17,
we prefer the constructor for direct-initialization and the conversion function
for copy-initialization, matching the behavior in C++14 and before. The
guaranteed copy elision rules were not intended to change the meaning of such
code (other than by removing unnecessary copy constructor calls).

This tweak will be raised with CWG.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=317066&r1=317065&r2=317066&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Oct 31 18:37:11 2017
@@ -8977,6 +8977,18 @@ bool clang::isBetterOverloadCandidate(
     // C++14 [over.match.best]p1 section 2 bullet 3.
   }
 
+  // FIXME: Work around a defect in the C++17 guaranteed copy elision wording,
+  // as combined with the resolution to CWG issue 243.
+  //
+  // When the context is initialization by constructor ([over.match.ctor] or
+  // either phase of [over.match.list]), a constructor is preferred over
+  // a conversion function.
+  if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 &&
+      Cand1.Function && Cand2.Function &&
+      isa<CXXConstructorDecl>(Cand1.Function) !=
+          isa<CXXConstructorDecl>(Cand2.Function))
+    return isa<CXXConstructorDecl>(Cand1.Function);
+
   //    -- F1 is a non-template function and F2 is a function template
   //       specialization, or, if not that,
   bool Cand1IsSpecialization = Cand1.Function &&
@@ -9035,20 +9047,6 @@ bool clang::isBetterOverloadCandidate(
         return true;
     }
   }
-  
-
-
-  // FIXME: Work around a defect in the C++17 guaranteed copy elision wording,
-  // as combined with the resolution to CWG issue 243.
-  //
-  // When the context is initialization by constructor ([over.match.ctor] or
-  // either phase of [over.match.list]), a constructor is preferred over
-  // a conversion function.
-  if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 &&
-      Cand1.Function && Cand2.Function &&
-      isa<CXXConstructorDecl>(Cand1.Function) !=
-          isa<CXXConstructorDecl>(Cand2.Function))
-    return isa<CXXConstructorDecl>(Cand1.Function);
 
   // Check for enable_if value-based overload resolution.
   if (Cand1.Function && Cand2.Function) {

Modified: cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp?rev=317066&r1=317065&r2=317066&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp Tue Oct 31 18:37:11 2017
@@ -160,3 +160,12 @@ struct AsDelegating final {
   // classes?
   AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}
 };
+
+namespace CtorTemplateBeatsNonTemplateConversionFn {
+  struct Foo { template <typename Derived> Foo(const Derived &); };
+  template <typename Derived> struct Base { operator Foo() const = delete; }; // expected-note {{deleted}}
+  struct Derived : Base<Derived> {};
+
+  Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}}
+  Foo g(Derived d) { return Foo(d); } // ok, calls constructor
+}




More information about the cfe-commits mailing list