-----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);