When performing a derived-to-base cast on the right-hand side of the
synthesized move assignment within an implicitly-defined move assignment operator, be sure to treat the derived-to-base cast as an xvalue (rather than an lvalue). Otherwise, we'll end up getting the wrong constructor. Optimize a direct call to a trivial move assignment operator to an aggregate copy, as we do for trivial copy assignment operators, and update the the assertion in CodeGenFunction::EmitAggregateCopy() to cope with this optimization. Fixes PR10860. llvm-svn: 139143
This commit is contained in:
parent
a098436b32
commit
146b8e9a58
|
@ -1069,7 +1069,9 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
|
|||
if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
|
||||
assert((Record->hasTrivialCopyConstructor() ||
|
||||
Record->hasTrivialCopyAssignment()) &&
|
||||
Record->hasTrivialCopyAssignment() ||
|
||||
Record->hasTrivialMoveConstructor() ||
|
||||
Record->hasTrivialMoveAssignment()) &&
|
||||
"Trying to aggregate-copy a type without a trivial copy "
|
||||
"constructor or assignment operator");
|
||||
// Ignore empty classes in C++.
|
||||
|
|
|
@ -334,16 +334,12 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
|
|||
LValue LV = EmitLValue(E->getArg(0));
|
||||
llvm::Value *This = LV.getAddress();
|
||||
|
||||
if (MD->isCopyAssignmentOperator()) {
|
||||
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
|
||||
if (ClassDecl->hasTrivialCopyAssignment()) {
|
||||
assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
|
||||
"EmitCXXOperatorMemberCallExpr - user declared copy assignment");
|
||||
llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
|
||||
QualType Ty = E->getType();
|
||||
EmitAggregateCopy(This, Src, Ty);
|
||||
return RValue::get(This);
|
||||
}
|
||||
if ((MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) &&
|
||||
MD->isTrivial()) {
|
||||
llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
|
||||
QualType Ty = E->getType();
|
||||
EmitAggregateCopy(This, Src, Ty);
|
||||
return RValue::get(This);
|
||||
}
|
||||
|
||||
llvm::Value *Callee = EmitCXXOperatorMemberCallee(E, MD, This);
|
||||
|
|
|
@ -7847,7 +7847,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
|
|||
// appropriately-qualified base type.
|
||||
Expr *From = OtherRef;
|
||||
From = ImpCastExprToType(From, BaseType, CK_UncheckedDerivedToBase,
|
||||
VK_RValue, &BasePath).take();
|
||||
VK_XValue, &BasePath).take();
|
||||
|
||||
// Dereference "this".
|
||||
ExprResult To = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
|
||||
|
|
|
@ -61,9 +61,25 @@ struct I {
|
|||
unsigned var[1];
|
||||
};
|
||||
|
||||
// CHECK: define void @_Z1hv() nounwind {
|
||||
void h() {
|
||||
I i;
|
||||
// CHECK: call void @llvm.memcpy.
|
||||
i = I();
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
// PR10860
|
||||
struct Empty { };
|
||||
struct VirtualWithEmptyBase : Empty {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
// CHECK: define void @_Z25move_VirtualWithEmptyBaseR20VirtualWithEmptyBaseS0_
|
||||
void move_VirtualWithEmptyBase(VirtualWithEmptyBase &x, VirtualWithEmptyBase &y) {
|
||||
// CHECK: call {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_
|
||||
x = static_cast<VirtualWithEmptyBase&&>(y);
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
// move assignment ops
|
||||
|
@ -76,8 +92,12 @@ void h() {
|
|||
// CHECK-ASSIGN: br i1
|
||||
// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_
|
||||
|
||||
// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1IaSEOS_
|
||||
// call void @llvm.memcpy.
|
||||
// VirtualWithEmptyBase move assignment operatpr
|
||||
// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN20VirtualWithEmptyBaseaSEOS_
|
||||
// CHECK-ASSIGN: store
|
||||
// CHECK-ASSIGN-NEXT: store
|
||||
// CHECK-NOT: call
|
||||
// CHECK: ret
|
||||
|
||||
// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1CaSEOS_
|
||||
// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_
|
||||
|
|
Loading…
Reference in New Issue