зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
9ffce2182e
Коммит
c743571e24
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче