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
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 24f7531..f3bb9a5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1867,7 +1867,6 @@
// the temporary or to a sub-object within the
// temporary.
//
- //
// The constructor that would be used to make the copy
// shall be callable whether or not the copy is actually
// done.
@@ -1915,6 +1914,20 @@
return true;
}
+ // If at least one of the types is a class type, the types are not
+ // related, and we aren't allowed any user conversions, the
+ // reference binding fails. This case is important for breaking
+ // recursion, since TryImplicitConversion below will attempt to
+ // create a temporary through the use of a copy constructor.
+ if (SuppressUserConversions && RefRelationship == Ref_Incompatible &&
+ (T1->isRecordType() || T2->isRecordType())) {
+ if (!ICS)
+ Diag(Init->getSourceRange().getBegin(),
+ diag::err_typecheck_convert_incompatible)
+ << DeclType << Init->getType() << "initializing" << Init->getSourceRange();
+ return true;
+ }
+
// Actually try to convert the initializer to T1.
if (ICS) {
/// C++ [over.ics.ref]p2: