This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR42883
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 28 Jan 2010 13:54:29 +0100 (CET)
- Subject: [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();
+ }
+ }