This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix REE from using freed memory (PR bootstrap/52041)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>, Richard Guenther <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 31 Jan 2012 09:19:15 +0100
- Subject: [PATCH] Fix REE from using freed memory (PR bootstrap/52041)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
find_removable_extensions/add_removable_extensions was storing pointers
into the *insn_list vector in def_map array. Unfortunately when
the vector is reallocated, this may result in all the pointers pointing
into freed memory. Detected by valgrind, fixed by instead just
storing the vector indexes (+ 1, so that 0 means former NULL),
bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
For 4.8 I think the def_map array could be dropped altogether, now
that we keep the UD/DU links, but this change looks smaller and safer.
2012-01-31 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/52041
PR bootstrap/52039
PR target/51974
* ree.c (add_removable_extension): Change def_map argument
to unsigned *, store in def_map 1 + offset into *insn_list vector
instead of pointers into the vector.
(find_removable_extensions): Adjust caller.
--- gcc/ree.c.jj 2012-01-30 00:10:01.205444366 +0100
+++ gcc/ree.c 2012-01-30 22:54:00.864425203 +0100
@@ -747,10 +747,11 @@ combine_reaching_defs (ext_cand *cand, c
static void
add_removable_extension (const_rtx expr, rtx insn,
VEC (ext_cand, heap) **insn_list,
- ext_cand **def_map)
+ unsigned *def_map)
{
enum rtx_code code;
enum machine_mode mode;
+ unsigned int idx;
rtx src, dest;
/* We are looking for SET (REG N) (ANY_EXTEND (REG N)). */
@@ -786,7 +787,8 @@ add_removable_extension (const_rtx expr,
/* Second, make sure the reaching definitions don't feed another and
different extension. FIXME: this obviously can be improved. */
for (def = defs; def; def = def->next)
- if ((cand = def_map[INSN_UID(DF_REF_INSN (def->ref))])
+ if ((idx = def_map[INSN_UID(DF_REF_INSN (def->ref))])
+ && (cand = VEC_index (ext_cand, *insn_list, idx - 1))
&& (cand->code != code || cand->mode != mode))
{
if (dump_file)
@@ -805,9 +807,10 @@ add_removable_extension (const_rtx expr,
cand->code = code;
cand->mode = mode;
cand->insn = insn;
+ idx = VEC_length (ext_cand, *insn_list);
for (def = defs; def; def = def->next)
- def_map[INSN_UID(DF_REF_INSN (def->ref))] = cand;
+ def_map[INSN_UID(DF_REF_INSN (def->ref))] = idx;
}
}
@@ -820,7 +823,7 @@ find_removable_extensions (void)
VEC (ext_cand, heap) *insn_list = NULL;
basic_block bb;
rtx insn, set;
- ext_cand **def_map = XCNEWVEC (ext_cand *, max_insn_uid);
+ unsigned *def_map = XCNEWVEC (unsigned, max_insn_uid);
FOR_EACH_BB (bb)
FOR_BB_INSNS (bb, insn)
Jakub