]> granicus.if.org Git - clang/commitdiff
Make sure to set vtable pointers in the destructors as well.
authorAnders Carlsson <andersca@mac.com>
Sun, 7 Feb 2010 19:45:40 +0000 (19:45 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 7 Feb 2010 19:45:40 +0000 (19:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95525 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/CodeGen/CGException.cpp
lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/vtable-pointer-initialization.cpp [new file with mode: 0644]

index fb2c9583d4a6c4a3b4de312fe9d9de16cc28d981..522fee488c6c9f12e4178d147984caad814c7a87 100644 (file)
@@ -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();
 }
index 85db6bb973a761b6469f45d06f6cf817827a63af..60a1016cc040b2bb4b11d3b618a73225146bcf99 100644 (file)
@@ -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();
index 44ed9db3474a486eb02bba22ecba997d8a3026c1..4eeea8eea79dcbc385f7598fded2c99ab8b54062 100644 (file)
@@ -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 (file)
index 0000000..92e0117
--- /dev/null
@@ -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