aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDeclCXX.cpp12
-rw-r--r--test/CXX/special/class.copy/implicit-move-def.cpp46
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_