Hey cool. Thanks. I was just looking at that. Beer on me next time you make it out. :)
-eric On Mar 20, 2012, at 12:49 PM, Benjamin Kramer <[email protected]> wrote: > Author: d0k > Date: Tue Mar 20 14:49:14 2012 > New Revision: 153115 > > URL: http://llvm.org/viewvc/llvm-project?rev=153115&view=rev > Log: > Debug info: Tighten up uses of plain MDNode pointers which don't survive > replaceOperandWith. > > TrackingVH notices when it gets RAUW'd. Fixes PR12305 and PR12315. > > Added: > cfe/trunk/test/CodeGenCXX/debug-info-use-after-free.cpp > Modified: > cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > > Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=153115&r1=153114&r2=153115&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Mar 20 14:49:14 2012 > @@ -1199,10 +1199,9 @@ > > if (FwdDecl.isForwardDecl()) > return FwdDecl; > - > - llvm::MDNode *MN = FwdDecl; > - llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN; > - > + > + llvm::TrackingVH<llvm::MDNode> FwdDeclNode(FwdDecl); > + > // Push the struct on region stack. > LexicalBlockStack.push_back(FwdDeclNode); > RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl); > @@ -1246,15 +1245,15 @@ > // get some enums in llvm/Analysis/DebugInfo.h to refer to > // them. > if (RD->isUnion()) > - MN->replaceOperandWith(10, Elements); > + FwdDeclNode->replaceOperandWith(10, Elements); > else if (CXXDecl) { > - MN->replaceOperandWith(10, Elements); > - MN->replaceOperandWith(13, TParamsArray); > + FwdDeclNode->replaceOperandWith(10, Elements); > + FwdDeclNode->replaceOperandWith(13, TParamsArray); > } else > - MN->replaceOperandWith(10, Elements); > + FwdDeclNode->replaceOperandWith(10, Elements); > > - RegionMap[Ty->getDecl()] = llvm::WeakVH(MN); > - return llvm::DIType(MN); > + RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDeclNode); > + return llvm::DIType(FwdDeclNode); > } > > /// CreateType - get objective-c object type. > @@ -1305,8 +1304,7 @@ > // will find it and we're emitting the complete type. > CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl; > // Push the struct on region stack. > - llvm::MDNode *MN = RealDecl; > - llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN; > + llvm::TrackingVH<llvm::MDNode> FwdDeclNode(RealDecl); > > LexicalBlockStack.push_back(FwdDeclNode); > RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl); > @@ -1401,10 +1399,10 @@ > } > > llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); > - RealDecl->replaceOperandWith(10, Elements); > + FwdDeclNode->replaceOperandWith(10, Elements); > > LexicalBlockStack.pop_back(); > - return RealDecl; > + return llvm::DIType(FwdDeclNode); > } > > llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) > { > @@ -1814,7 +1812,7 @@ > uint64_t Size = CGM.getContext().getTypeSize(Ty); > uint64_t Align = CGM.getContext().getTypeAlign(Ty); > const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); > - llvm::MDNode *RealDecl = NULL; > + llvm::TrackingVH<llvm::MDNode> RealDecl; > > if (RD->isUnion()) > RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line, > > Added: cfe/trunk/test/CodeGenCXX/debug-info-use-after-free.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-use-after-free.cpp?rev=153115&view=auto > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/debug-info-use-after-free.cpp (added) > +++ cfe/trunk/test/CodeGenCXX/debug-info-use-after-free.cpp Tue Mar 20 > 14:49:14 2012 > @@ -0,0 +1,312 @@ > +// RUN: %clang_cc1 -g -emit-llvm-only %s > +// Check that we don't crash. > +// PR12305, PR12315 > + > +# 1 "a.h" 3 > +template < typename T1 > struct Types1 > +{ > + typedef T1 Head; > +}; > +template < typename > struct Types; > +template < template < typename > class Tmpl > struct TemplateSel > +{ > + template < typename T > struct Bind > + { > + typedef Tmpl < T > type; > + }; > +}; > +template < typename > struct NoneT; > +template < template < typename > class T1, template < typename > class > > struct Templates2 > +{ > + typedef TemplateSel < T1 > Head; > +}; > +template < template < typename > class, template < typename > class = > + NoneT, template < typename > class = NoneT, template < typename > class = > + NoneT > struct Templates; > +template < template < typename > class T1, > + template < typename > class T2 > struct Templates <T1, T2 > > +{ > + typedef Templates2 < T1, T2 > type; > +}; > +template < typename T > struct TypeList > +{ > + typedef Types1 < T > type; > +}; > +template < template < typename > class, class TestSel, > + typename Types > class TypeParameterizedTest > +{ > +public:static bool Register () > + { > + typedef typename Types::Head Type; > + typename TestSel::template Bind < Type >::type TestClass; > +}}; > + > +template < template < typename > class Fixture, typename Tests, > + typename Types > class TypeParameterizedTestCase > +{ > +public:static bool Register (char *, char *, int *) > + { > + typedef typename Tests::Head Head; > + TypeParameterizedTest < Fixture, Head, Types >::Register; > +}}; > + > +template < typename > class TypedTestP1 > +{ > +}; > + > +namespace gtest_case_TypedTestP1_ > +{ > + template < typename gtest_TypeParam_ > class A:TypedTestP1 < > + gtest_TypeParam_ > > + { > + }; > +template < typename gtest_TypeParam_ > class B:TypedTestP1 < > + gtest_TypeParam_ > > + { > + }; > + typedef Templates < A >::type gtest_AllTests_; > +} > + > +template < typename > class TypedTestP2 > +{ > +}; > + > +namespace gtest_case_TypedTestP2_ > +{ > + template < typename gtest_TypeParam_ > class A:TypedTestP2 < > + gtest_TypeParam_ > > + { > + }; > + typedef Templates < A >::type gtest_AllTests_; > +} > + > +bool gtest_Int_TypedTestP1 = > + TypeParameterizedTestCase < TypedTestP1, > + gtest_case_TypedTestP1_::gtest_AllTests_, > + TypeList < int >::type >::Register ("Int", "TypedTestP1", 0); > +bool gtest_Int_TypedTestP2 = > + TypeParameterizedTestCase < TypedTestP2, > + gtest_case_TypedTestP2_::gtest_AllTests_, > + TypeList < Types < int > >::type >::Register ("Int", "TypedTestP2", 0); > + > +template < typename _Tp > struct new_allocator > +{ > + typedef _Tp *pointer; > + template < typename > struct rebind { > + typedef new_allocator other; > + }; > +}; > +template < typename _Tp > struct allocator:new_allocator < _Tp > { > +}; > +template < typename _Tp, typename _Alloc > struct _Vector_base { > + typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type; > + struct _Vector_impl { > + typename _Tp_alloc_type::pointer _M_end_of_storage; > + }; > + _Vector_base () { > + foo((int *) this->_M_impl._M_end_of_storage); > + } > + void foo(int *); > + _Vector_impl _M_impl; > +}; > +template < typename _Tp, typename _Alloc = > +allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { }; > + > + > +template < class T> struct HHH {}; > +struct DDD { int x_;}; > +struct Data; > +struct X1; > +struct CCC:DDD { virtual void xxx (HHH < X1 >); }; > +template < class SSS > struct EEE:vector < HHH < SSS > > { }; > +template < class SSS, class = EEE < SSS > >class FFF { }; > +template < class SSS, class GGG = EEE < SSS > >class AAA:FFF <GGG> { }; > +class BBB:virtual CCC { > + void xxx (HHH < X1 >); > + vector < HHH < X1 > >aaa; > +}; > +class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; }; > +ZZZ * ZZZ::ppp () { return new ZZZ; } > + > +namespace std > +{ > + template < class, class > struct pair; > +} > +namespace __gnu_cxx { > +template < typename > class new_allocator; > +} > +namespace std { > +template < typename _Tp > class allocator:__gnu_cxx::new_allocator < _Tp > { > +}; > +template < typename, typename > struct _Vector_base { > +}; > +template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class > vector:_Vector_base < _Tp, > + _Alloc > + > { > + }; > +} > + > +namespace > +std { > + template < > + typename, > + typename > struct unary_function; > + template < > + typename, > + typename, > + typename > struct binary_function; > + template < > + typename > + _Tp > struct equal_to: > + binary_function < > + _Tp, > + _Tp, > + bool > { > + }; > + template < > + typename > + _Pair > struct _Select1st: > + unary_function < > + _Pair, > + typename > + _Pair::first_type > { > + }; > +} > +# 1 "f.h" 3 > +using > +std::pair; > +namespace > +__gnu_cxx { > + template < > + class > struct hash; > + template < > + class, > + class, > + class, > + class, > + class > + _EqualKey, > + class > > + class > + hashtable { > + public: > + typedef _EqualKey > + key_equal; > + }; > + using > + std::equal_to; > + using > + std::allocator; > + using > + std::_Select1st; > + template < class _Key, class _Tp, class _HashFn = > + hash < _Key >, class _EqualKey = equal_to < _Key >, class _Alloc = > + allocator < _Tp > >class hash_map { > + typedef > + hashtable < > + pair < > + _Key, > + _Tp >, > + _Key, > + _HashFn, > + _Select1st < > + pair < > + _Key, > + _Tp > >, > + _EqualKey, > + _Alloc > > + _Ht; > + public: > + typename _Ht::key_type; > + typedef typename > + _Ht::key_equal > + key_equal; > + }; > +} > +using > +__gnu_cxx::hash_map; > +class > +C2; > +template < class > class scoped_ptr { > +}; > +namespace { > +class > + AAA { > + virtual ~ > + AAA () { > + }}; > +} > +template < typename > class EEE; > +template < typename CCC, typename = > +typename CCC::key_equal, typename = > +EEE < CCC > >class III { > +}; > +namespace > +util { > + class > + EEE { > + }; > +} > +namespace { > +class > + C1: > + util::EEE { > + public: > + class > + C3: > + AAA { > + struct FFF; > + typedef > + III < > + hash_map < > + C2, > + FFF > > > + GGG; > + GGG > + aaa; > + friend > + C1; > + }; > + void > + HHH (C3::GGG &); > + }; > +} > +namespace > +n1 { > + class > + Test { > + }; > + template < > + typename > > + class > + C7 { > + }; > + class > + C4: > + n1::Test { > + vector < > + C1::C3 * > > + a1; > + }; > + enum C5 { }; > + class > + C6: > + C4, > + n1::C7 < > + C5 > { > + }; > + class > + C8: > + C6 { > + }; > + class > + C9: > + C8 { > + void > + TestBody (); > + }; > + void > + C9::TestBody () { > + scoped_ptr < C1::C3 > context; > + } > +} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
