This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR42883


This fixes a case where we mixup EH landing pad labels during
basic-block forwarding.  The solution is like with destinations
containing non-local labels to not forward such blocks, as
landing-pad labels have to come first.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2010-01-28  Richard Guenther  <rguenther@suse.de>

	PR middle-end/42883
	* tree-cfgcleanup.c (remove_forwarder_block): Do not remove
	the forwarder if the destination is an EH landing pad.

	* g++.dg/torture/pr42883.C: New testcase.

Index: gcc/tree-cfgcleanup.c
===================================================================
*** gcc/tree-cfgcleanup.c	(revision 156289)
--- gcc/tree-cfgcleanup.c	(working copy)
*************** remove_forwarder_block (basic_block bb)
*** 345,356 ****
    if (dest == bb)
      return false;
  
!   /* If the destination block consists of a nonlocal label, do not merge
!      it.  */
    label = first_stmt (dest);
    if (label
        && gimple_code (label) == GIMPLE_LABEL
!       && DECL_NONLOCAL (gimple_label_label (label)))
      return false;
  
    /* If there is an abnormal edge to basic block BB, but not into
--- 345,357 ----
    if (dest == bb)
      return false;
  
!   /* If the destination block consists of a nonlocal label or is a
!      EH landing pad, do not merge it.  */
    label = first_stmt (dest);
    if (label
        && gimple_code (label) == GIMPLE_LABEL
!       && (DECL_NONLOCAL (gimple_label_label (label))
! 	  || EH_LANDING_PAD_NR (gimple_label_label (label)) != 0))
      return false;
  
    /* If there is an abnormal edge to basic block BB, but not into
Index: gcc/testsuite/g++.dg/torture/pr42883.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr42883.C	(revision 0)
--- gcc/testsuite/g++.dg/torture/pr42883.C	(revision 0)
***************
*** 0 ****
--- 1,63 ----
+ // { dg-do compile }
+ 
+ typedef __SIZE_TYPE__ size_t;
+ namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) {
+     template<typename _Tp>     class new_allocator     {
+     public:
+ 	typedef size_t size_type;
+ 	typedef _Tp* pointer;
+ 	typedef _Tp& reference;
+ 	void       deallocate(pointer __p, size_type)       {
+ 	    ::operator delete(__p);
+ 	}
+     };
+ }
+ namespace std __attribute__ ((__visibility__ ("default"))) {
+     template<typename _Tp>     class allocator: public __gnu_cxx::new_allocator<_Tp>     {
+     public:
+ 	template<typename _Tp1>         struct rebind         {
+ 	    typedef allocator<_Tp1> other;
+ 	};
+     };
+     template<typename _Tp, typename _Alloc>     struct _Vector_base     {
+ 	typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+ 	struct _Vector_impl       : public _Tp_alloc_type       {
+ 	    typename _Tp_alloc_type::pointer _M_start;
+ 	    typename _Tp_alloc_type::pointer _M_end_of_storage;
+ 	};
+ 	~_Vector_base()       {
+ 	    _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage         - this->_M_impl._M_start);
+ 	}
+ 	_Vector_impl _M_impl;
+ 	void       _M_deallocate(typename _Tp_alloc_type::pointer __p, size_t __n)       {
+ 	    if (__p)    _M_impl.deallocate(__p, __n);
+ 	}
+     };
+     template<typename _Tp, typename _Alloc = std::allocator<_Tp> >     class vector : protected _Vector_base<_Tp, _Alloc>     {
+ 	typedef _Vector_base<_Tp, _Alloc> _Base;
+ 	typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
+     public:
+ 	typedef typename _Tp_alloc_type::reference reference;
+ 	typedef size_t size_type;
+ 	size_type       size() const       {
+ 	}
+ 	reference       operator[](size_type __n)       {
+ 	}
+     };
+ };
+ class vtkConvexPointSet  {
+ public:
+     static vtkConvexPointSet *New();
+ };
+ void MakeInternalMesh() {
+     std::vector< int > tempFaces[2];
+     std::vector< int > firstFace;
+     int i, j, k;
+     for(i = 0; i < 1000; i++)     {
+ 	for(int pointCount = 0; pointCount < 1000; pointCount++) 	{
+ 	    for(j = 0; j < (int)tempFaces[0].size(); k++)
+ 	      if(tempFaces[0][j] == tempFaces[1][k]) 		break;
+ 	}
+ 	vtkConvexPointSet::New();
+     }
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]