diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 12 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp | 16 |
2 files changed, 26 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index d82f9359716..c5c5693818b 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/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/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/clang/test/CodeGenCXX/copy-assign-synthesis-3.cpp new file mode 100644 index 00000000000..3dab0f2a81b --- /dev/null +++ b/clang/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; +} + |