This fixes PR52772 - prev_bb does not have any relation to the new
pre-landing-pad block (not sure what I was thinking here), so this
moves the loop updating code to the place where we connect the
new block into the CFG.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-30  Richard Guenther <rguent...@suse.de>

        PR middle-end/52780
        * except.c (emit_to_new_bb_before): Move loop updating ...
        (dw2_build_landing_pads): ... here.  Use a proper block for
        querying the loop father.

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

Index: gcc/except.c
===================================================================
*** gcc/except.c        (revision 186007)
--- gcc/except.c        (working copy)
*************** emit_to_new_bb_before (rtx seq, rtx insn
*** 918,929 ****
    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;
  }
  
--- 918,923 ----
*************** dw2_build_landing_pads (void)
*** 995,1000 ****
--- 989,1004 ----
        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);
+       }
      }
  }
  
Index: gcc/testsuite/g++.dg/torture/pr52772.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr52772.C      (revision 0)
--- gcc/testsuite/g++.dg/torture/pr52772.C      (revision 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);
+     }
+   }
+ }

Reply via email to