]> granicus.if.org Git - clang/commitdiff
Account for the VTT argument when making an implicit copy constructor for
authorJohn McCall <rjmccall@apple.com>
Fri, 30 Apr 2010 05:56:45 +0000 (05:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 30 Apr 2010 05:56:45 +0000 (05:56 +0000)
a class with virtual bases.  Just a patch until Sema starts (correctly) doing
most of this analysis.

Fixes PR 6622.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102692 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
test/CodeGenCXX/constructors.cpp

index 98ed1b3b2f05608cbd0e48ee3ce3a510dc9bc3e9..6345ca34bac357a8eb8f025446a4f5daa99b8916 100644 (file)
@@ -677,13 +677,25 @@ CodeGenFunction::EmitClassCopyAssignment(llvm::Value *Dest, llvm::Value *Src,
 void 
 CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) {
   const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
+  CXXCtorType CtorType = CurGD.getCtorType();
+  (void) CtorType;
+
   const CXXRecordDecl *ClassDecl = Ctor->getParent();
   assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
       "SynthesizeCXXCopyConstructor - copy constructor has definition already");
   assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
 
   llvm::Value *ThisPtr = LoadCXXThis();
-  llvm::Value *SrcPtr = Builder.CreateLoad(GetAddrOfLocalVar(Args[1].first));
+
+  // Find the source pointer.
+  unsigned SrcArgIndex = Args.size() - 1;
+  assert(CtorType == Ctor_Base || SrcArgIndex == 1);
+  assert(CtorType != Ctor_Base ||
+         (ClassDecl->getNumVBases() != 0 && SrcArgIndex == 2) ||
+         SrcArgIndex == 1);
+
+  llvm::Value *SrcPtr =
+    Builder.CreateLoad(GetAddrOfLocalVar(Args[SrcArgIndex].first));
 
   for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
        Base != ClassDecl->bases_end(); ++Base) {
index e0709055cdbb8dcdc7e38e92a9377debc4fbdb7f..a8dc7fcec703dcfdecc8e41af848c6240b01de2f 100644 (file)
@@ -92,3 +92,15 @@ D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
 // CHECK: call void @_ZN10ValueClassC1Eii(
 // CHECK: call void @_ZN1AC2E10ValueClass(
 // CHECK: call void @_ZN6MemberC1Ei(
+
+
+// PR6622:  this shouldn't crash
+namespace test0 {
+  struct A {};
+  struct B : virtual A { int x; };
+  struct C : B {};
+  
+  void test(C &in) {
+    C tmp = in;
+  }
+}