]> granicus.if.org Git - clang/commitdiff
Make copy assignment operator synthesis not explode for classes with complex
authorEli Friedman <eli.friedman@gmail.com>
Tue, 8 Dec 2009 01:57:53 +0000 (01:57 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 8 Dec 2009 01:57:53 +0000 (01:57 +0000)
or non-record aggregate members.

It might be worth spending some time to optimize this code (and the parallel
code for copy constructors) to memcpy in larger chunks, rather than copying
one member at a time.  Not sure exactly how beneficial that would be, but
it seems like could help for large classes with, for example, a vtable pointer
forcing the generation of a copy constructor.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90823 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/copy-assign-synthesis-3.cpp [new file with mode: 0644]

index d82f9359716e954a84fbcf3614dadf3e34aca23d..c5c5693818bfd8a98394e6688c2f0b9d19e5f18f 100644 (file)
@@ -1655,8 +1655,16 @@ void CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
     // Do a built-in assignment of scalar data members.
     LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
     LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
-    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
-    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
+    if (!hasAggregateLLVMType(Field->getType())) {
+      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
+      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
+    } else if (Field->getType()->isAnyComplexType()) {
+      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
+                                               RHS.isVolatileQualified());
+      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
+    } else {
+      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
+    }
   }
 
   // return *this;
diff --git a/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/test/CodeGenCXX/copy-assign-synthesis-3.cpp
new file mode 100644 (file)
index 0000000..3dab0f2
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: clang-cc -emit-llvm-only -verify %s
+
+struct A {
+  A& operator=(const A&);
+};
+
+struct B {
+  A a;
+  float b;
+  int (A::*c)();
+  _Complex float d;
+};
+void a(B& x, B& y) {
+  x = y;
+}
+