]> granicus.if.org Git - clang/commitdiff
Steve set me straight on this one. GCC was right, EDG was wrong: the
authorDouglas Gregor <dgregor@apple.com>
Mon, 2 Feb 2009 22:11:10 +0000 (22:11 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 2 Feb 2009 22:11:10 +0000 (22:11 +0000)
direct-initialization following a user-defined conversion can select
any constructor; it just can't employ any user-defined
conversions. So we ban those conversions and classify the constructor
call based on the relationship between the "from" and "to" types in
the conversion.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63554 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaCXX/user-defined-conversions.cpp

index 1fa703c775ab4157830c3bfc1a958225b748bc79..7219f19a97cc6a9b13e0582f31f94ec6a66af915 100644 (file)
@@ -383,7 +383,10 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
     //   called for those cases.
     if (CXXConstructorDecl *Constructor 
           = dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
-      if (Constructor->isCopyConstructor(Context)) {
+      QualType FromCanon 
+        = Context.getCanonicalType(From->getType().getUnqualifiedType());
+      QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+      if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) {
         // Turn this into a "standard" conversion sequence, so that it
         // gets ranked with standard conversion sequences.
         ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
@@ -391,8 +394,7 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
         ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr();
         ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr();
         ICS.Standard.CopyConstructor = Constructor;
-        if (IsDerivedFrom(From->getType().getUnqualifiedType(),
-                          ToType.getUnqualifiedType()))
+        if (ToCanon != FromCanon)
           ICS.Standard.Second = ICK_Derived_To_Base;
       }
     }
index e4b12fc3f713f0862b668faba79bf205a361ed7d..c6941b947ee1aba6a940d7a85fc944bb140bc64e 100644 (file)
@@ -65,5 +65,5 @@ void test_conversion(ConvertibleToBase ctb, ConvertibleToDerived ctd,
   Base b2(ctb);
   Base b3 = ctd;
   Base b4(ctd);
-  Base b5 = ctfd; // expected-error{{cannot initialize 'b5' with an lvalue of type 'struct ConvertibleToFunkyDerived'}}
+  Base b5 = ctfd;
 }