aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-22 00:21:20 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-22 00:21:20 +0000
commit0d6d12b2db47ff34d6cd30917992a8c8ad97aac2 (patch)
treeb28e68e577d9001bdc336713413c6f1bf073b432
parentd6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8 (diff)
When converting from a type to itself or one of its base classes via a
constructor call, the conversion is only a standard conversion sequence if that constructor is a copy constructor. This fixes PR5834 in a semi-lame way, because the "real" fix will be to move over to InitializationSequence. That will happen "soonish", but not now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91861 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaOverload.cpp3
-rw-r--r--test/CodeGenCXX/PR5834-constructor-conversion.cpp14
2 files changed, 16 insertions, 1 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fbcb807428..66aa4845b1 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -451,7 +451,8 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
QualType FromCanon
= Context.getCanonicalType(From->getType().getUnqualifiedType());
QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
- if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) {
+ if (Constructor->isCopyConstructor(Context) &&
+ (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;
diff --git a/test/CodeGenCXX/PR5834-constructor-conversion.cpp b/test/CodeGenCXX/PR5834-constructor-conversion.cpp
new file mode 100644
index 0000000000..044d8e555d
--- /dev/null
+++ b/test/CodeGenCXX/PR5834-constructor-conversion.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// PR5834
+struct ASTMultiMover {};
+struct ASTMultiPtr {
+ ASTMultiPtr();
+ ASTMultiPtr(ASTMultiPtr&);
+ ASTMultiPtr(ASTMultiMover mover);
+ operator ASTMultiMover();
+};
+void f1() {
+ extern void f0(ASTMultiPtr);
+ f0(ASTMultiPtr());
+}