From: Douglas Gregor Date: Sun, 25 Apr 2010 00:55:24 +0000 (+0000) Subject: When copying a temporary object to initialize an entity for which the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b86cf0c11712fa89f14197f3f0ed862e7b2add84;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102290 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e1269a7e12..c413e67f04 100644 --- a/lib/Sema/SemaInit.cpp +++ b/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/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 463f1899ed..06b5fcb318 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/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/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 4aad3c0056..f9a9ed100a 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/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); + } +}