I work on target with complex mode switching needs, so it can happen that
in some block, for an entity a mode is provided without the need for a set.
This causes the current optimize_mode_switching to crash when it later
dereferences a NULL seginfo pointer.
Fixed by using an actual flag to keep track if we have allocated any seginfo.

Bootstrappded on x86_64-unknown-linux-gnu.
2011-07-08  Joern Rennecke <joern.renne...@embecosm.com>

        * mode-switching.c (optimize_mode_switching): Fix bug in MODE_AFTER
        handling.

Index: mode-switching.c
===================================================================
--- mode-switching.c    (revision 1670)
+++ mode-switching.c    (revision 1671)
@@ -499,6 +499,7 @@ optimize_mode_switching (void)
        {
          struct seginfo *ptr;
          int last_mode = no_mode;
+         bool any_set_required = false;
          HARD_REG_SET live_now;
 
          REG_SET_TO_HARD_REG_SET (live_now, df_get_live_in (bb));
@@ -527,6 +528,7 @@ optimize_mode_switching (void)
 
                  if (mode != no_mode && mode != last_mode)
                    {
+                     any_set_required = true;
                      last_mode = mode;
                      ptr = new_seginfo (mode, insn, bb->index, live_now);
                      add_seginfo (info + bb->index, ptr);
@@ -548,8 +550,10 @@ optimize_mode_switching (void)
            }
 
          info[bb->index].computing = last_mode;
-         /* Check for blocks without ANY mode requirements.  */
-         if (last_mode == no_mode)
+         /* Check for blocks without ANY mode requirements.
+            N.B. because of MODE_AFTER, last_mode might still be different
+            from no_mode.  */
+         if (!any_set_required)
            {
              ptr = new_seginfo (no_mode, BB_END (bb), bb->index, live_now);
              add_seginfo (info + bb->index, ptr);

Reply via email to