mirror of
https://github.com/intel/llvm.git
synced 2026-02-05 04:46:27 +08:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user