diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-12-08 01:57:53 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-12-08 01:57:53 +0000 |
commit | ebc3317c66638a05a089abb348877b9b823f52b0 (patch) | |
tree | 838655d71aa044be4aeb56ec7baab715710749e7 | |
parent | e3fdca2ee0346a41d9cc5ee417a75e66274216f5 (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.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/copy-assign-synthesis-3.cpp | 16 |
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; +} + |