]> granicus.if.org Git - clang/commitdiff
When defining the implicit move assignment operator, don't perform
authorDouglas Gregor <dgregor@apple.com>
Thu, 1 Sep 2011 02:09:07 +0000 (02:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 1 Sep 2011 02:09:07 +0000 (02:09 +0000)
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

lib/Sema/SemaDeclCXX.cpp
test/CXX/special/class.copy/implicit-move-def.cpp

index df0a5226c0f02ed426ad1d4ef194b04b221a4967..91895f0687ab75e1b7f1ab3773172d8bb03d2bbe 100644 (file)
@@ -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() && 
index 84a41c4622f3369c82575f2ee2961eb2897e85b2..1f91945b4a9f76c3fde96516122606e53de39cfb 100644 (file)
@@ -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_