Currently we're initializing the vtable pointers of a class only after
the bases are completely initialized.  This won't work --- base
initializer expressions can rely on the vtables having been set up.
Check for uses of 'this' in the initializers and force a vtable
initialization if found.

This might not be good enough;  we might need to extend this to handle
the possibility of arbitrary code finding an external reference to this
(not yet completely-constructed!) object and accessing through it,
in which case we'll probably find ourselves doing a lot more unnecessary
stores.

llvm-svn: 114153
diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp
index 284b8b5..d610fd5 100644
--- a/clang/test/CodeGenCXX/constructor-init.cpp
+++ b/clang/test/CodeGenCXX/constructor-init.cpp
@@ -81,6 +81,38 @@
   // CHECK: ret void
 }
 
+// Make sure we initialize the vtable pointer if it's required by a
+// base initializer.
+namespace InitVTable {
+  struct A { A(int); };
+  struct B : A {
+    virtual int foo();
+    B();
+    B(int);
+  };
+
+  // CHECK: define void @_ZN10InitVTable1BC2Ev(
+  // CHECK:      [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i8***
+  // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+  // CHECK:      [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}}
+  // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0
+  // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]]
+  // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]])
+  // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* %1, i32 [[ARG]])
+  // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i8***
+  // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+  // CHECK-NEXT: ret void
+  B::B() : A(foo()) {}
+
+  // CHECK: define void @_ZN10InitVTable1BC2Ei(
+  // CHECK:      [[ARG:%.*]] = add nsw i32 {{%.*}}, 5
+  // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
+  // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i8***
+  // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+  // CHECK-NEXT: ret void
+  B::B(int x) : A(x + 5) {}
+}
+
 template<typename T>
 struct X {
   X(const X &);