diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-30 23:27:23 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-30 23:27:23 +0000 |
commit | 734d9869efb5d126df53ba70a6060789887e0d68 (patch) | |
tree | a9032656d874ab03253c8ea9738c28d09b6adda9 /lib/Sema/SemaOverload.cpp | |
parent | ad53eff73224b29955da59f65e6b9eba1a5f6b76 (diff) |
Improve our handling of the second step in a user-defined conversion
sequence. Previously, we weren't permitting the second step to call
copy constructors, which left user-defined conversion sequences
surprisingly broken.
Now, we perform overload resolution among all of the constructors, but
only accept the result if it makes the conversion a standard
conversion. Note that this behavior is different from both GCC and EDG
(which don't agree with each other, either); I've submitted a core
issue on the matter.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 17ad387ac3..1fa703c775 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -366,13 +366,13 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD, ImplicitConversionSequence Sema::TryImplicitConversion(Expr* From, QualType ToType, bool SuppressUserConversions, - bool AllowExplict) + bool AllowExplicit) { ImplicitConversionSequence ICS; if (IsStandardConversion(From, ToType, ICS.Standard)) ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; - else if (!SuppressUserConversions && - IsUserDefinedConversion(From, ToType, ICS.UserDefined, AllowExplict)) { + else if (IsUserDefinedConversion(From, ToType, ICS.UserDefined, + !SuppressUserConversions, AllowExplicit)) { ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion; // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class @@ -396,6 +396,17 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, ICS.Standard.Second = ICK_Derived_To_Base; } } + + // C++ [over.best.ics]p4: + // However, when considering the argument of a user-defined + // conversion function that is a candidate by 13.3.1.3 when + // invoked for the copying of the temporary in the second step + // of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or + // 13.3.1.6 in all cases, only standard conversion sequences and + // ellipsis conversion sequences are allowed. + if (SuppressUserConversions && + ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) + ICS.ConversionKind = ImplicitConversionSequence::BadConversion; } else ICS.ConversionKind = ImplicitConversionSequence::BadConversion; @@ -1188,17 +1199,23 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) FromType.getUnqualifiedType() == ToType.getUnqualifiedType(); } -/// IsUserDefinedConversion - Determines whether there is a -/// user-defined conversion sequence (C++ [over.ics.user]) that -/// converts expression From to the type ToType. If such a conversion -/// exists, User will contain the user-defined conversion sequence -/// that performs such a conversion and this routine will return -/// true. Otherwise, this routine returns false and User is -/// unspecified. AllowExplicit is true if the conversion should -/// consider C++0x "explicit" conversion functions as well as -/// non-explicit conversion functions (C++0x [class.conv.fct]p2). +/// Determines whether there is a user-defined conversion sequence +/// (C++ [over.ics.user]) that converts expression From to the type +/// ToType. If such a conversion exists, User will contain the +/// user-defined conversion sequence that performs such a conversion +/// and this routine will return true. Otherwise, this routine returns +/// false and User is unspecified. +/// +/// \param AllowConversionFunctions true if the conversion should +/// consider conversion functions at all. If false, only constructors +/// will be considered. +/// +/// \param AllowExplicit true if the conversion should consider C++0x +/// "explicit" conversion functions as well as non-explicit conversion +/// functions (C++0x [class.conv.fct]p2). bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, + bool AllowConversionFunctions, bool AllowExplicit) { OverloadCandidateSet CandidateSet; @@ -1226,8 +1243,11 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, } } - if (const CXXRecordType *FromRecordType - = dyn_cast_or_null<CXXRecordType>(From->getType()->getAsRecordType())) { + if (!AllowConversionFunctions) { + // Don't allow any conversion functions to enter the overload set. + } else if (const CXXRecordType *FromRecordType + = dyn_cast_or_null<CXXRecordType>( + From->getType()->getAsRecordType())) { // Add all of the conversion functions as candidates. // FIXME: Look for conversions in base classes! CXXRecordDecl *FromRecordDecl = FromRecordType->getDecl(); |