-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This fixes a couple use-after-free problems and one use-after-free
non-problem.

In cfgrtl.c, redirect_branch_edge may delete its first argument, so this
code is clearly erroneous:

          e->flags &= ~EDGE_FALLTHRU;
          redirected = redirect_branch_edge (e, dest);
          gcc_assert (redirected);
          e->flags |= EDGE_FALLTHRU;
          df_set_bb_dirty (e->src);
          return e;

This fix is obvious, use REDIRECTED rather than E after the call to
redirect_branch_edge.

Similarly for redirect_edge_succ_nodup in this fragment:

        ret = redirect_edge_succ_nodup (e, dest);
        if (dump_file)
        fprintf (dump_file, "Fallthru edge %i->%i redirected to %i\n",
                 e->src->index, e->dest->index, dest->index);
      }
Luckily in this case the use-after-free only occurs when dumping, so it
won't typically affect end users.


The non-problem is this code in cfg.c:

        if (s->probability > REG_BR_PROB_BASE)
        s->probability = REG_BR_PROB_BASE;
        s->count += e->count;
        remove_edge (e);
        redirect_edge_var_map_dup (s, e);
        e = s;

remove_edge frees E, when we then use in redirect_edge_var_map_dup.
Luckily we only care about the pointer value of E which doesn't change.
 Regardless, I fixed this to keep the static checkers quiet.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.  Ok for
the trunk?

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNh4zMAAoJEBRtltQi2kC7LFMH/j5/rNrFTvxX9mEv0qV4ezGk
fGuuitZfKEqXFY1oSKiyhawPpql0RbmmAJAOg4RHQzMnxMdUFJXcxpLzuXQG6TOr
9IapfQHi7siUKyAGq3OKChXFL+6Gx+NiTP7Ll8l6zSoF41FNEbrkHxfD0FXj/fkI
7JJyOsJEfrAbZiffU6e828Ku6mYwPc6wbDhk1YekFgZKQWfYDbkExZ2/twEyH1hO
yPMHgC0Jd9Nysnj1lxxDeGIW0Jhzej14aC8ugfzzMf/auj1hOIjk4t8k6KKSYvTu
ZzX5rHxfel0xDwAXbum/M38pgnEUznl6kIbLDiJOBJfIA/YBdDk+XTyB99OLcdc=
=QNh1
-----END PGP SIGNATURE-----
        * cfg.c (redirect_edge_succ_nodup): Duplicate the var map
        before removing the edge.

        * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Do not use
        E after it may have been freed by redirect_branch_edge or
        redirect_edge_succ_nodup.

Index: cfg.c
===================================================================
*** cfg.c       (revision 171074)
--- cfg.c       (working copy)
*************** redirect_edge_succ_nodup (edge e, basic_
*** 402,409 ****
        if (s->probability > REG_BR_PROB_BASE)
        s->probability = REG_BR_PROB_BASE;
        s->count += e->count;
-       remove_edge (e);
        redirect_edge_var_map_dup (s, e);
        e = s;
      }
    else
--- 402,409 ----
        if (s->probability > REG_BR_PROB_BASE)
        s->probability = REG_BR_PROB_BASE;
        s->count += e->count;
        redirect_edge_var_map_dup (s, e);
+       remove_edge (e);
        e = s;
      }
    else
Index: cfgrtl.c
===================================================================
*** cfgrtl.c    (revision 171074)
--- cfgrtl.c    (working copy)
*************** cfg_layout_redirect_edge_and_branch (edg
*** 2537,2545 ****
          e->flags &= ~EDGE_FALLTHRU;
          redirected = redirect_branch_edge (e, dest);
          gcc_assert (redirected);
!         e->flags |= EDGE_FALLTHRU;
!         df_set_bb_dirty (e->src);
!         return e;
        }
        /* In case we are redirecting fallthru edge to the branch edge
         of conditional jump, remove it.  */
--- 2537,2545 ----
          e->flags &= ~EDGE_FALLTHRU;
          redirected = redirect_branch_edge (e, dest);
          gcc_assert (redirected);
!         redirected->flags |= EDGE_FALLTHRU;
!         df_set_bb_dirty (redirected->src);
!         return redirected;
        }
        /* In case we are redirecting fallthru edge to the branch edge
         of conditional jump, remove it.  */
*************** cfg_layout_redirect_edge_and_branch (edg
*** 2556,2562 ****
        ret = redirect_edge_succ_nodup (e, dest);
        if (dump_file)
        fprintf (dump_file, "Fallthru edge %i->%i redirected to %i\n",
!                e->src->index, e->dest->index, dest->index);
      }
    else
      ret = redirect_branch_edge (e, dest);
--- 2556,2562 ----
        ret = redirect_edge_succ_nodup (e, dest);
        if (dump_file)
        fprintf (dump_file, "Fallthru edge %i->%i redirected to %i\n",
!                ret->src->index, ret->dest->index, dest->index);
      }
    else
      ret = redirect_branch_edge (e, dest);

Reply via email to