diff options
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 12 | ||||
-rw-r--r-- | test/CXX/special/class.copy/implicit-move-def.cpp | 46 |
2 files changed, 38 insertions, 20 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index df0a5226c0..91895f0687 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -7901,9 +7901,15 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, Size *= ArraySize; } - // Take the address of the field references for "from" and "to". - From = CreateBuiltinUnaryOp(Loc, UO_AddrOf, From.get()); - To = CreateBuiltinUnaryOp(Loc, UO_AddrOf, To.get()); + // Take the address of the field references for "from" and "to". We + // directly construct UnaryOperators here because semantic analysis + // does not permit us to take the address of an xvalue. + From = new (Context) UnaryOperator(From.get(), UO_AddrOf, + Context.getPointerType(From.get()->getType()), + VK_RValue, OK_Ordinary, Loc); + To = new (Context) UnaryOperator(To.get(), UO_AddrOf, + Context.getPointerType(To.get()->getType()), + VK_RValue, OK_Ordinary, Loc); bool NeedsCollectableMemCpy = (BaseType->isRecordType() && diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp index 84a41c4622..1f91945b4a 100644 --- a/test/CXX/special/class.copy/implicit-move-def.cpp +++ b/test/CXX/special/class.copy/implicit-move-def.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm -o - -std=c++0x %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -std=c++0x %s | FileCheck -check-prefix=CHECK-ASSIGN %s +// RUN: %clang_cc1 -emit-llvm -o - -std=c++0x %s | FileCheck -check-prefix=CHECK-CTOR %s // construct @@ -55,30 +56,41 @@ void g() { d = D(); } +// PR10822 +struct I { + unsigned var[1]; +}; + +void h() { + I i; + i = I(); +} // move assignment ops -// CHECK: define linkonce_odr {{.*}} @_ZN1DaSEOS_ -// CHECK: call {{.*}} @_ZN1CaSEOS_ -// CHECK: call {{.*}} @_ZN1AaSEOS_ -// CHECK: call {{.*}} @_ZN1BaSEOS_ +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1DaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1CaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1BaSEOS_ // array loop -// CHECK: br i1 -// CHECK: call {{.*}} @_ZN1AaSEOS_ +// CHECK-ASSIGN: br i1 +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ -// CHECK: define linkonce_odr {{.*}} @_ZN1CaSEOS_ -// CHECK: call {{.*}} @_ZN1AaSEOS_ +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1IaSEOS_ +// call void @llvm.memcpy. +// CHECK-ASSIGN: define linkonce_odr {{.*}} @_ZN1CaSEOS_ +// CHECK-ASSIGN: call {{.*}} @_ZN1AaSEOS_ // move ctors -// CHECK: define linkonce_odr void @_ZN1HC2EOS_ -// CHECK: call void @_ZN1GC2EOS_ -// CHECK: call void @_ZN1FC1EOS_ -// CHECK: call void @_ZN1EC1EOS_ +// CHECK-CTOR: define linkonce_odr void @_ZN1HC2EOS_ +// CHECK-CTOR: call void @_ZN1GC2EOS_ +// CHECK-CTOR: call void @_ZN1FC1EOS_ +// CHECK-CTOR: call void @_ZN1EC1EOS_ // array loop -// CHECK: br i1 -// CHECK: call void @_ZN1FC1EOS_ +// CHECK-CTOR: br i1 +// CHECK-CTOR: call void @_ZN1FC1EOS_ -// CHECK: define linkonce_odr void @_ZN1GC2EOS_ -// CHECK: call void @_ZN1EC1EOS_ +// CHECK-CTOR: define linkonce_odr void @_ZN1GC2EOS_ +// CHECK-CTOR: call void @_ZN1EC1EOS_ |