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
diff --git a/clang/test/CXX/special/class.copy/implicit-move-def.cpp b/clang/test/CXX/special/class.copy/implicit-move-def.cpp
index 1f91945..fde80fb 100644
--- a/clang/test/CXX/special/class.copy/implicit-move-def.cpp
+++ b/clang/test/CXX/special/class.copy/implicit-move-def.cpp
@@ -61,9 +61,25 @@
   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 @@
 // 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_