Fix two bugs with temporaries:
1. For A f() { return A(); } we were incorrectly calling the A destructor on the returned object. 2. For void f(A); void g() { A a; f(a); } we were incorrectly not calling the copy constructor. llvm-svn: 87082
This commit is contained in:
parent
87f84c1e72
commit
78cfaa9e56
|
@ -671,8 +671,13 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
|
|||
// Code gen optimization to eliminate copy constructor and return
|
||||
// its first argument instead.
|
||||
if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
|
||||
CXXConstructExpr::const_arg_iterator i = E->arg_begin();
|
||||
EmitAggExpr((*i), Dest, false);
|
||||
const Expr *Arg = E->getArg(0);
|
||||
|
||||
if (const CXXBindTemporaryExpr *BindExpr =
|
||||
dyn_cast<CXXBindTemporaryExpr>(Arg))
|
||||
Arg = BindExpr->getSubExpr();
|
||||
|
||||
EmitAggExpr(Arg, Dest, false);
|
||||
return;
|
||||
}
|
||||
if (Array) {
|
||||
|
|
|
@ -2652,6 +2652,8 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
|
|||
// Pass the argument.
|
||||
if (PerformCopyInitialization(Arg, ProtoArgType, "passing"))
|
||||
return true;
|
||||
|
||||
Arg = MaybeBindToTemporary(Arg).takeAs<Expr>();
|
||||
} else {
|
||||
ParmVarDecl *Param = FDecl->getParamDecl(i);
|
||||
|
||||
|
|
|
@ -162,6 +162,29 @@ C::C()
|
|||
|
||||
// CHECK: call void @_ZN6PR50771BD1Ev
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
A f8() {
|
||||
// CHECK: call void @_ZN1AC1Ev
|
||||
// CHECK-NOT: call void @_ZN1AD1Ev
|
||||
return A();
|
||||
// CHECK: ret void
|
||||
}
|
||||
|
||||
struct H {
|
||||
H();
|
||||
~H();
|
||||
H(const H&);
|
||||
};
|
||||
|
||||
void f9(H h) {
|
||||
// CHECK: call void @_ZN1HC1Ev
|
||||
// CHECK: call void @_Z2f91H
|
||||
// CHECK: call void @_ZN1HD1Ev
|
||||
f9(H());
|
||||
|
||||
// CHECK: call void @_ZN1HC1ERKS_
|
||||
// CHECK: call void @_Z2f91H
|
||||
// CHECK: call void @_ZN1HD1Ev
|
||||
f9(h);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue