From d0ace024965bb68e3d4a5a082f1b94fa56253198 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 25 Apr 2010 00:55:24 +0000 Subject: [PATCH] When copying a temporary object to initialize an entity for which the temporary needs to be bound, bind the copy object. Otherwise, we won't end up calling the destructor for the copy. Fixes Boost.Optional. llvm-svn: 102290 --- clang/lib/Sema/SemaInit.cpp | 10 ++++++++-- clang/lib/Sema/SemaOverload.cpp | 2 +- clang/test/CodeGenCXX/temporaries.cpp | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index e1269a7e1297..c413e67f042c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3355,8 +3355,14 @@ static Sema::OwningExprResult CopyObject(Sema &S, Loc, ConstructorArgs)) return S.ExprError(); - return S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable, - move_arg(ConstructorArgs)); + // Actually perform the constructor call. + CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable, + move_arg(ConstructorArgs)); + + // If we're supposed to bind temporaries, do so. + if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity)) + CurInit = S.MaybeBindToTemporary(CurInit.takeAs()); + return move(CurInit); } void InitializationSequence::PrintInitLocationNote(Sema &S, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 463f1899ed9b..06b5fcb318c3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3703,7 +3703,7 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { const RecordType *TyRec; if (const MemberPointerType *RHSMPType = ArgExpr->getType()->getAs()) - TyRec = cast(RHSMPType->getClass()); + TyRec = RHSMPType->getClass()->getAs(); else TyRec = ArgExpr->getType()->getAs(); if (!TyRec) { diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index 4aad3c0056ca..f9a9ed100ab5 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -301,3 +301,21 @@ namespace PR6648 { zed(foo); } } + +namespace UserConvertToValue { + struct X { + X(int); + X(const X&); + ~X(); + }; + + void f(X); + + // CHECK: void @_ZN18UserConvertToValue1gEv() + void g() { + // CHECK: call void @_ZN18UserConvertToValue1XC1Ei + // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE + // CHECK: call void @_ZN18UserConvertToValue1XD1Ev + f(1); + } +} -- GitLab