forked from OSchip/llvm-project
Make sure to set vtable pointers in the destructors as well.
llvm-svn: 95525
This commit is contained in:
parent
6d0e5bd8f3
commit
ff8cce4395
|
@ -1043,7 +1043,7 @@ void CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
|
||||||
|
|
||||||
StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
|
StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
|
InitializeVtablePtrs(Dtor->getParent());
|
||||||
EmitDtorEpilogue(Dtor, DtorType);
|
EmitDtorEpilogue(Dtor, DtorType);
|
||||||
FinishFunction();
|
FinishFunction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,6 +473,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
|
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
|
||||||
PushCleanupBlock(DtorEpilogue);
|
PushCleanupBlock(DtorEpilogue);
|
||||||
|
|
||||||
|
InitializeVtablePtrs(DD->getParent());
|
||||||
EmitStmt(S.getTryBlock());
|
EmitStmt(S.getTryBlock());
|
||||||
|
|
||||||
CleanupBlockInfo Info = PopCleanupBlock();
|
CleanupBlockInfo Info = PopCleanupBlock();
|
||||||
|
|
|
@ -283,6 +283,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
|
||||||
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
|
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
|
||||||
PushCleanupBlock(DtorEpilogue);
|
PushCleanupBlock(DtorEpilogue);
|
||||||
|
|
||||||
|
InitializeVtablePtrs(DD->getParent());
|
||||||
|
|
||||||
EmitStmt(S);
|
EmitStmt(S);
|
||||||
|
|
||||||
CleanupBlockInfo Info = PopCleanupBlock();
|
CleanupBlockInfo Info = PopCleanupBlock();
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||||
|
|
||||||
|
struct Field {
|
||||||
|
Field();
|
||||||
|
~Field();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base {
|
||||||
|
Base();
|
||||||
|
~Base();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct A : Base {
|
||||||
|
A();
|
||||||
|
~A();
|
||||||
|
|
||||||
|
virtual void f();
|
||||||
|
|
||||||
|
Field field;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CHECK: define void @_ZN1AC1Ev(
|
||||||
|
// CHECK: call void @_ZN4BaseC2Ev(
|
||||||
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
|
||||||
|
// CHECK: call void @_ZN5FieldC1Ev(
|
||||||
|
// CHECK: ret void
|
||||||
|
A::A() { }
|
||||||
|
|
||||||
|
// CHECK: define void @_ZN1AD1Ev(
|
||||||
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
|
||||||
|
// CHECK: call void @_ZN5FieldD1Ev(
|
||||||
|
// CHECK: call void @_ZN4BaseD2Ev(
|
||||||
|
// CHECK: ret void
|
||||||
|
A::~A() { }
|
||||||
|
|
||||||
|
struct B : Base {
|
||||||
|
virtual void f();
|
||||||
|
|
||||||
|
Field field;
|
||||||
|
};
|
||||||
|
|
||||||
|
void f() { B b; }
|
||||||
|
|
||||||
|
// CHECK: define linkonce_odr void @_ZN1BC1Ev(
|
||||||
|
// CHECK: call void @_ZN4BaseC2Ev(
|
||||||
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
|
||||||
|
// CHECK: call void @_ZN5FieldC1Ev
|
||||||
|
// CHECK: ret void
|
||||||
|
|
||||||
|
// CHECK: define linkonce_odr void @_ZN1BD1Ev(
|
||||||
|
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
|
||||||
|
// CHECK: call void @_ZN5FieldD1Ev(
|
||||||
|
// CHECK: call void @_ZN4BaseD2Ev(
|
||||||
|
// CHECK: ret void
|
Loading…
Reference in New Issue