[cfe-commits] r153115 - in /cfe/trunk: lib/CodeGen/CGDebugInfo.cpp test/CodeGenCXX/debug-info-use-after-free.cpp

Eric Christopher echristo at apple.com
Tue Mar 20 13:13:42 PDT 2012


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 <benny.kra at googlemail.com> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list