aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-12-08 01:57:53 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-12-08 01:57:53 +0000
commitebc3317c66638a05a089abb348877b9b823f52b0 (patch)
tree838655d71aa044be4aeb56ec7baab715710749e7
parente3fdca2ee0346a41d9cc5ee417a75e66274216f5 (diff)
Make copy assignment operator synthesis not explode for classes with complex
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
-rw-r--r--lib/CodeGen/CGCXX.cpp12
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis-3.cpp16
2 files changed, 26 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index d82f935971..c5c5693818 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -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
index 0000000000..3dab0f2a81
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis-3.cpp
@@ -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;
+}
+