aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-09-01 02:09:07 +0000
committerDouglas Gregor <dgregor@apple.com>2011-09-01 02:09:07 +0000
commit45d3d716622f12f9d8e77f2e4c8ffddf4bfe3559 (patch)
tree63053d59f73900496afc7992ef2d6f2032dc67ef
parente6b8d68a927368b06ac06cc9ac9e7f60aa966d5f (diff)
When defining the implicit move assignment operator, don't perform
semantic analysis when taking the address of an xvalue. Instead, just build the unary operator directly, since it's safe to do so (from the IRgen and AST perspectives) for any glvalue. Fixes PR10822. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138935 91177308-0d34-0410-b5e6-96231b3b80d8
-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_