diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/except.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr52772.C | 85 |
4 files changed, 107 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2afe362..151e5a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-03-30 Richard Guenther <rguenther@suse.de> + + PR middle-end/52772 + * except.c (emit_to_new_bb_before): Move loop updating ... + (dw2_build_landing_pads): ... here. Use a proper block for + querying the loop father. + 2012-03-30 Tristan Gingold <gingold@adacore.com> * config/ia64/ia64.c (ia64_section_type_flags): Remove diff --git a/gcc/except.c b/gcc/except.c index ddc8652..e3a9ef0 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -918,12 +918,6 @@ emit_to_new_bb_before (rtx seq, rtx insn) bb = create_basic_block (seq, last, prev_bb); update_bb_for_insn (bb); bb->flags |= BB_SUPERBLOCK; - if (current_loops) - { - add_bb_to_loop (bb, prev_bb->loop_father); - if (prev_bb->loop_father->header == prev_bb) - prev_bb->loop_father->header = bb; - } return bb; } @@ -995,6 +989,16 @@ dw2_build_landing_pads (void) e = make_edge (bb, bb->next_bb, e_flags); e->count = bb->count; e->probability = REG_BR_PROB_BASE; + if (current_loops) + { + struct loop *loop = bb->next_bb->loop_father; + /* If we created a pre-header block, add the new block to the + outer loop, otherwise to the loop itself. */ + if (bb->next_bb == loop->header) + add_bb_to_loop (bb, loop_outer (loop)); + else + add_bb_to_loop (bb, loop); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 498218a..fb232b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-03-30 Richard Guenther <rguenther@suse.de> + + PR middle-end/52772 + * g++.dg/torture/pr52772.C: New testcase. + 2012-03-29 Paolo Carlini <paolo.carlini@oracle.com> PR c++/52718 diff --git a/gcc/testsuite/g++.dg/torture/pr52772.C b/gcc/testsuite/g++.dg/torture/pr52772.C new file mode 100644 index 0000000..810e657 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr52772.C @@ -0,0 +1,85 @@ +// { dg-do compile } + +typedef __SIZE_TYPE__ size_t; + +class c1; + +class c2 { + public: c2() { }; + void *operator new(size_t size, const c1 & crc1); +}; + +class c3 { + public: c3() { _Obj = 0; } + ~c3() { if (_Obj) delete _Obj; } + void set(c2 *pObj); + protected: c2 *_Obj; +}; + +void c3::set(c2 *pObj) { _Obj = pObj; }; + +template<class TYPE> class tc1 : public c2 { + public: tc1(int n=0){}; + int get() const; + TYPE& operator[] (int id); + TYPE * _data; + int _size; +}; + +template<class TYPE> TYPE & tc1<TYPE>::operator[] (int id) { + return _data[id]; +} + +template<class TYPE> int tc1<TYPE>::get() const { + return _size; +} + +class c4 { + public: c4(); +}; + +class c5 : public c2 { + protected: c2 * _own; + public: c5(c2 *o) : _own(o) { } + c5(const c4 & box); + int add(const c4 & ext); +}; + +class c6 { + public: int get() const {}; +}; + +class c7 { + friend class c8; + int find(c6 * loop) const; +}; + +class c8 { + const c1 & _rc1; + int tria(c7 * face, c5 * vtree0 = 0); +}; + +int c8::tria(c7 * face, c5 * vtree0) { + c6 *sLData[64]; + tc1<c6*> loops(64); + while (loops.get() > 1) { + c6 *iloop = 0; + for (int j=1; j<loops.get(); j++) { + if (loops[j]->get() < 32) { + iloop = loops[j]; + } + } + face->find(iloop); + } + c4 box; + c3 ctree; + c5 *vtree = vtree0; + if (!vtree) { + vtree = new (_rc1) c5(box); + ctree.set(vtree); + for (int j=0; j<1; j++) { + c4 sVBBox; + vtree->add(sVBBox); + } + } +} |