aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-25 00:55:24 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-25 00:55:24 +0000
commitb86cf0c11712fa89f14197f3f0ed862e7b2add84 (patch)
tree11221796e90bf8aa03f15bf189a3bc250ac30cc0
parent8e142ccf1196c9ae31f10f9caa97670e343971e7 (diff)
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
-rw-r--r--lib/Sema/SemaInit.cpp10
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--test/CodeGenCXX/temporaries.cpp18
3 files changed, 27 insertions, 3 deletions
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<Expr>());
+ 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<MemberPointerType>())
- TyRec = cast<RecordType>(RHSMPType->getClass());
+ TyRec = RHSMPType->getClass()->getAs<RecordType>();
else
TyRec = ArgExpr->getType()->getAs<RecordType>();
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);
+ }
+}