diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-06 16:26:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-06 16:26:56 +0000 |
commit | 146b8e9a587e17d06346f546998da4c57cb2df77 (patch) | |
tree | c09ccaceff559aa14e35c2db9b8be1b17ec40e71 /clang/test/CXX/special/class.copy/implicit-move-def.cpp | |
parent | a098436b327a40f5709fa0ec2cb0f875b7ac8a2f (diff) | |
download | bcm5719-llvm-146b8e9a587e17d06346f546998da4c57cb2df77.tar.gz bcm5719-llvm-146b8e9a587e17d06346f546998da4c57cb2df77.zip |
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
Diffstat (limited to 'clang/test/CXX/special/class.copy/implicit-move-def.cpp')
-rw-r--r-- | clang/test/CXX/special/class.copy/implicit-move-def.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
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 1f91945b4a9..fde80fbd7de 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 @@ 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_ |