From: Benjamin Kramer Date: Sun, 27 May 2012 22:41:08 +0000 (+0000) Subject: PR12962: Fix a rare use after free when collecting virtual overrides. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0cf31dc263979027f345c00318a704c5f5b1e76;p=clang 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 218673090a..7e278ff234 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -505,12 +505,17 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD, 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 0000000000..85995971d2 --- /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(); };