summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp36
-rw-r--r--clang/test/CodeGenCXX/copy-constructor-synthesis.cpp11
2 files changed, 39 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 19cc04bace2..e1b67393390 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -1366,10 +1366,11 @@ CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
Base->getType());
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
- FieldEnd = ClassDecl->field_end();
- Field != FieldEnd; ++Field) {
- QualType FieldType = getContext().getCanonicalType((*Field)->getType());
+ for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); I != E; ++I) {
+ const FieldDecl *Field = *I;
+
+ QualType FieldType = getContext().getCanonicalType(Field->getType());
const ConstantArrayType *Array =
getContext().getAsConstantArrayType(FieldType);
if (Array)
@@ -1378,8 +1379,8 @@ CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
- LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
- LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
+ LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
+ LValue RHS = EmitLValueForField(LoadOfSrc, Field, false, 0);
if (Array) {
const llvm::Type *BasePtr = ConvertType(FieldType);
BasePtr = llvm::PointerType::getUnqual(BasePtr);
@@ -1395,9 +1396,28 @@ CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
0 /*ClassDecl*/, FieldClassDecl, FieldType);
continue;
}
+
+ if (Field->getType()->isReferenceType()) {
+ unsigned FieldIndex = CGM.getTypes().getLLVMFieldNo(Field);
+
+ llvm::Value *LHS = Builder.CreateStructGEP(LoadOfThis, FieldIndex,
+ "lhs.ref");
+
+ llvm::Value *RHS = Builder.CreateStructGEP(LoadOfThis, FieldIndex,
+ "rhs.ref");
+
+ // Load the value in RHS.
+ RHS = Builder.CreateLoad(RHS);
+
+ // And store it in the LHS
+ Builder.CreateStore(RHS, LHS);
+
+ continue;
+ }
// Do a built-in assignment of scalar data members.
- LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
- LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
+ LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
+ LValue RHS = EmitLValueForField(LoadOfSrc, Field, false, 0);
+
if (!hasAggregateLLVMType(Field->getType())) {
RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 3b8f7821abc..2e950eb9e9b 100644
--- a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -102,6 +102,17 @@ int main() {
m1.pr();
}
+struct A {
+};
+
+struct B : A {
+ A &a;
+};
+
+void f(const B &b1) {
+ B b2(b1);
+}
+
// CHECK-LP64: .globl __ZN1XC1ERKS_
// CHECK-LP64: .weak_definition __ZN1XC1ERKS_
// CHECK-LP64: __ZN1XC1ERKS_:
OpenPOWER on IntegriCloud