PR12962: Fix a rare use after free when collecting virtual overrides.

The DenseMap reallocates after 64 insertions so this only happened in
large test cases under very specific circumstances.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157549 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 2186730..7e278ff 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -505,12 +505,17 @@
       CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
       if (Base->isVirtual()) {
         CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
+        BaseOverriders = MyVirtualOverriders;
         if (!MyVirtualOverriders) {
           MyVirtualOverriders = new CXXFinalOverriderMap;
+
+          // Collect may cause VirtualOverriders to reallocate, invalidating the
+          // MyVirtualOverriders reference. Set BaseOverriders to the right
+          // value now.
+          BaseOverriders = MyVirtualOverriders;
+
           Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders);
         }
-
-        BaseOverriders = MyVirtualOverriders;
       } else
         Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders);
 
diff --git a/test/SemaCXX/long-virtual-inheritance-chain.cpp b/test/SemaCXX/long-virtual-inheritance-chain.cpp
new file mode 100644
index 0000000..8599597
--- /dev/null
+++ b/test/SemaCXX/long-virtual-inheritance-chain.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+class test0                   { virtual void f(); };
+class test1  : virtual test0  { virtual void f(); };
+class test2  : virtual test1  { virtual void f(); };
+class test3  : virtual test2  { virtual void f(); };
+class test4  : virtual test3  { virtual void f(); };
+class test5  : virtual test4  { virtual void f(); };
+class test6  : virtual test5  { virtual void f(); };
+class test7  : virtual test6  { virtual void f(); };
+class test8  : virtual test7  { virtual void f(); };
+class test9  : virtual test8  { virtual void f(); };
+class test10 : virtual test9  { virtual void f(); };
+class test11 : virtual test10 { virtual void f(); };
+class test12 : virtual test11 { virtual void f(); };
+class test13 : virtual test12 { virtual void f(); };
+class test14 : virtual test13 { virtual void f(); };
+class test15 : virtual test14 { virtual void f(); };
+class test16 : virtual test15 { virtual void f(); };
+class test17 : virtual test16 { virtual void f(); };
+class test18 : virtual test17 { virtual void f(); };
+class test19 : virtual test18 { virtual void f(); };
+class test20 : virtual test19 { virtual void f(); };
+class test21 : virtual test20 { virtual void f(); };
+class test22 : virtual test21 { virtual void f(); };
+class test23 : virtual test22 { virtual void f(); };
+class test24 : virtual test23 { virtual void f(); };
+class test25 : virtual test24 { virtual void f(); };
+class test26 : virtual test25 { virtual void f(); };
+class test27 : virtual test26 { virtual void f(); };
+class test28 : virtual test27 { virtual void f(); };
+class test29 : virtual test28 { virtual void f(); };
+class test30 : virtual test29 { virtual void f(); };
+class test31 : virtual test30 { virtual void f(); };
+class test32 : virtual test31 { virtual void f(); };
+class test33 : virtual test32 { virtual void f(); };
+class test34 : virtual test33 { virtual void f(); };
+class test35 : virtual test34 { virtual void f(); };
+class test36 : virtual test35 { virtual void f(); };
+class test37 : virtual test36 { virtual void f(); };
+class test38 : virtual test37 { virtual void f(); };
+class test39 : virtual test38 { virtual void f(); };
+class test40 : virtual test39 { virtual void f(); };
+class test41 : virtual test40 { virtual void f(); };
+class test42 : virtual test41 { virtual void f(); };
+class test43 : virtual test42 { virtual void f(); };
+class test44 : virtual test43 { virtual void f(); };
+class test45 : virtual test44 { virtual void f(); };
+class test46 : virtual test45 { virtual void f(); };
+class test47 : virtual test46 { virtual void f(); };
+class test48 : virtual test47 { virtual void f(); };
+class test49 : virtual test48 { virtual void f(); };
+class test50 : virtual test49 { virtual void f(); };