gcc-patches@gcc.gnu.org
[Top] [All Lists]

Re: patch for mainline to fix latent bug in flow.c

Subject: Re: patch for mainline to fix latent bug in flow.c
From: Kenneth Zadeck
Date: Sun, 18 Dec 2005 21:36:56 -0500
Ian Lance Taylor wrote:
Kenneth Zadeck <zadeck@xxxxxxxxxxxxxxxxx> writes:

On the dataflow branch, where the dataflow is good enough so that some
of the
rtl transformations are actually effective, it is possible to pass a
set of blocks to update_life_info and have the cleanup_cfg step inside
it actually delete one of the blocks of interest. Unfortunately, there
is no plumbing for cleanup_cfg to pass back this information back to
flow so the rest of flow is run with an blocks sbitmap that has an
entry for a deleted block.  There are two places downstream of the
call to cleanup_cfg that will ice if this happens.

I do not have a test case that causes this failure on the mainline.
However, this does happen on the dataflow branch and the logic is the
same on the mainline so there is no reason why it could not happen
there. Kenny

This is OK with a ChangeLog entry, if it has passed bootstrap and
testing.

Thanks.

Ian
committed

bootstrapped and regression tested on suse 10.0 on x86-32.

2005-12-17  Kenneth Zadeck <zadeck@xxxxxxxxxxxxxxxxx>

       * flow.c (update_life_info, count_or_remove_death_notes): Fixed
   latent bug that could happen if update_life_info was called with a
   blocks parameter and the call to cleanup_cfg actually deleted one
   of those blocks.

Kenny
Index: flow.c
===================================================================
--- flow.c      (revision 108761)
+++ flow.c      (working copy)
@@ -658,12 +658,16 @@ update_life_info (sbitmap blocks, enum u
       EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
        {
          bb = BASIC_BLOCK (i);
-
-         COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
-         propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
-
-         if (extent == UPDATE_LIFE_LOCAL)
-           verify_local_live_at_start (tmp, bb);
+         if (bb)
+           {
+             /* The bitmap may be flawed in that one of the basic
+                blocks may have been deleted before you get here.  */
+             COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
+             propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
+             
+             if (extent == UPDATE_LIFE_LOCAL)
+               verify_local_live_at_start (tmp, bb);
+           }
        };
     }
   else
@@ -4456,7 +4460,11 @@ count_or_remove_death_notes (sbitmap blo
 
       EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
        {
-         count += count_or_remove_death_notes_bb (BASIC_BLOCK (i), kill);
+         basic_block bb = BASIC_BLOCK (i);
+         /* The bitmap may be flawed in that one of the basic blocks
+            may have been deleted before you get here.  */
+         if (bb)
+           count += count_or_remove_death_notes_bb (bb, kill);
        };
     }
   else
<Prev in Thread] Current Thread [Next in Thread>