Account for the VTT argument when making an implicit copy constructor for

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
This commit is contained in:
John McCall 2010-04-30 05:56:45 +00:00
Родитель 9ffce2182e
Коммит c743571e24
2 изменённых файлов: 25 добавлений и 1 удалений

Просмотреть файл

@ -677,13 +677,25 @@ CodeGenFunction::EmitClassCopyAssignment(llvm::Value *Dest, llvm::Value *Src,
void void
CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) { CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) {
const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
CXXCtorType CtorType = CurGD.getCtorType();
(void) CtorType;
const CXXRecordDecl *ClassDecl = Ctor->getParent(); const CXXRecordDecl *ClassDecl = Ctor->getParent();
assert(!ClassDecl->hasUserDeclaredCopyConstructor() && assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
"SynthesizeCXXCopyConstructor - copy constructor has definition already"); "SynthesizeCXXCopyConstructor - copy constructor has definition already");
assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
llvm::Value *ThisPtr = LoadCXXThis(); 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(); for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
Base != ClassDecl->bases_end(); ++Base) { Base != ClassDecl->bases_end(); ++Base) {

Просмотреть файл

@ -92,3 +92,15 @@ D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
// CHECK: call void @_ZN10ValueClassC1Eii( // CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass( // CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei( // 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;
}
}