aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-07 19:45:40 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-07 19:45:40 +0000
commit1851a12605bc6f1ea70d11974a315340ebaab6eb (patch)
treeaa75366648d8cf95699bfef4330be6655e04b438
parent585fa68ca00421af6c8289866a7bde27a8e8c0ce (diff)
Make sure to set vtable pointers in the destructors as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95525 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGClass.cpp2
-rw-r--r--lib/CodeGen/CGException.cpp1
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp54
4 files changed, 58 insertions, 1 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index fb2c9583d4..522fee488c 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1043,7 +1043,7 @@ void CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
SourceLocation());
-
+ InitializeVtablePtrs(Dtor->getParent());
EmitDtorEpilogue(Dtor, DtorType);
FinishFunction();
}
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 85db6bb973..60a1016cc0 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -473,6 +473,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
PushCleanupBlock(DtorEpilogue);
+ InitializeVtablePtrs(DD->getParent());
EmitStmt(S.getTryBlock());
CleanupBlockInfo Info = PopCleanupBlock();
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 44ed9db347..4eeea8eea7 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -283,6 +283,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
PushCleanupBlock(DtorEpilogue);
+ InitializeVtablePtrs(DD->getParent());
+
EmitStmt(S);
CleanupBlockInfo Info = PopCleanupBlock();
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
new file mode 100644
index 0000000000..92e011752f
--- /dev/null
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -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