r227169 - DR1902: if overload resolution recurses, and the inner overload resolution

Richard Smith richard-llvm at metafoo.co.uk
Mon Jan 26 19:30:40 PST 2015


Author: rsmith
Date: Mon Jan 26 21:30:40 2015
New Revision: 227169

URL: http://llvm.org/viewvc/llvm-project?rev=227169&view=rev
Log:
DR1902: if overload resolution recurses, and the inner overload resolution
selects a deleted function, the outer function is still a candidate even though
the initialization sequence is "otherwise ill-formed".

Added:
    cfe/trunk/test/CXX/drs/dr19xx.cpp
Modified:
    cfe/trunk/lib/Sema/SemaOverload.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=227169&r1=227168&r2=227169&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 26 21:30:40 2015
@@ -1098,11 +1098,11 @@ TryUserDefinedConversion(Sema &S, Expr *
   // Attempt user-defined conversion.
   OverloadCandidateSet Conversions(From->getExprLoc(),
                                    OverloadCandidateSet::CSK_Normal);
-  OverloadingResult UserDefResult
-    = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
-                              AllowExplicit, AllowObjCConversionOnExplicit);
-
-  if (UserDefResult == OR_Success) {
+  switch (IsUserDefinedConversion(S, From, ToType, ICS.UserDefined,
+                                  Conversions, AllowExplicit,
+                                  AllowObjCConversionOnExplicit)) {
+  case OR_Success:
+  case OR_Deleted:
     ICS.setUserDefined();
     ICS.UserDefined.Before.setAsIdentityConversion();
     // C++ [over.ics.user]p4:
@@ -1131,16 +1131,24 @@ TryUserDefinedConversion(Sema &S, Expr *
           ICS.Standard.Second = ICK_Derived_To_Base;
       }
     }
-  } else if (UserDefResult == OR_Ambiguous && !SuppressUserConversions) {
-    ICS.setAmbiguous();
-    ICS.Ambiguous.setFromType(From->getType());
-    ICS.Ambiguous.setToType(ToType);
-    for (OverloadCandidateSet::iterator Cand = Conversions.begin();
-         Cand != Conversions.end(); ++Cand)
-      if (Cand->Viable)
-        ICS.Ambiguous.addConversion(Cand->Function);
-  } else {
+    break;
+
+  case OR_Ambiguous:
+    if (!SuppressUserConversions) {
+      ICS.setAmbiguous();
+      ICS.Ambiguous.setFromType(From->getType());
+      ICS.Ambiguous.setToType(ToType);
+      for (OverloadCandidateSet::iterator Cand = Conversions.begin();
+           Cand != Conversions.end(); ++Cand)
+        if (Cand->Viable)
+          ICS.Ambiguous.addConversion(Cand->Function);
+      break;
+    }
+
+    // Fall through.
+  case OR_No_Viable_Function:
     ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
+    break;
   }
 
   return ICS;
@@ -3129,8 +3137,10 @@ IsUserDefinedConversion(Sema &S, Expr *F
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
 
   OverloadCandidateSet::iterator Best;
-  switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
+  switch (auto Result = CandidateSet.BestViableFunction(S, From->getLocStart(),
+                                                        Best, true)) {
   case OR_Success:
+  case OR_Deleted:
     // Record the standard conversion we used and the conversion function.
     if (CXXConstructorDecl *Constructor
           = dyn_cast<CXXConstructorDecl>(Best->Function)) {
@@ -3158,7 +3168,7 @@ IsUserDefinedConversion(Sema &S, Expr *F
       User.After.setAsIdentityConversion();
       User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
       User.After.setAllToTypes(ToType);
-      return OR_Success;
+      return Result;
     }
     if (CXXConversionDecl *Conversion
                  = dyn_cast<CXXConversionDecl>(Best->Function)) {
@@ -3184,15 +3194,12 @@ IsUserDefinedConversion(Sema &S, Expr *F
       //   user-defined conversion sequence (see 13.3.3 and
       //   13.3.3.1).
       User.After = Best->FinalConversion;
-      return OR_Success;
+      return Result;
     }
     llvm_unreachable("Not a constructor or conversion function?");
 
   case OR_No_Viable_Function:
     return OR_No_Viable_Function;
-  case OR_Deleted:
-    // No conversion here! We're done.
-    return OR_Deleted;
 
   case OR_Ambiguous:
     return OR_Ambiguous;

Added: cfe/trunk/test/CXX/drs/dr19xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr19xx.cpp?rev=227169&view=auto
==============================================================================
--- cfe/trunk/test/CXX/drs/dr19xx.cpp (added)
+++ cfe/trunk/test/CXX/drs/dr19xx.cpp Mon Jan 26 21:30:40 2015
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr1902 { // dr1902: 3.7
+  struct A {};
+  struct B {
+    B(A);
+#if __cplusplus >= 201103L
+        // expected-note at -2 {{candidate}}
+#endif
+
+    B() = delete;
+#if __cplusplus < 201103L
+        // expected-error at -2 {{extension}}
+#endif
+
+    B(const B&) // expected-note {{deleted here}}
+#if __cplusplus >= 201103L
+        // expected-note at -2 {{candidate}}
+#else
+        // expected-error at +2 {{extension}}
+#endif
+        = delete;
+
+    operator A();
+  };
+
+  extern B b1;
+  B b2(b1); // expected-error {{call to deleted}}
+
+#if __cplusplus >= 201103L
+  // This is ambiguous, even though calling the B(const B&) constructor would
+  // both directly and indirectly call a deleted function.
+  B b({}); // expected-error {{ambiguous}}
+#endif
+}

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=227169&r1=227168&r2=227169&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Mon Jan 26 21:30:40 2015
@@ -11227,7 +11227,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1902">1902</a></td>
     <td>DR</td>
     <td>What makes a conversion “otherwise ill-formed”?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="1903">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1903">1903</a></td>





More information about the cfe-commits mailing list