aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+}
+