Message ID | 20101210194523.GR29412@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Fri, Dec 10, 2010 at 08:45:23PM +0100, Jakub Jelinek wrote: > > On the attached testcase f951 ICEs under valgrind (and on a larger > testcase can ICE even without it), because a charlen is freed, eventhough > it is actually referenced. > > The problem is with IMPLICIT charlen, gfc_new_charlen with non-NULL old_cl > generates a copy of a charlen, which is then attached to an implicitly > typed symbol, but if reject_statement is called afterwards, the charlen > copy is freed, eventhough a pointer to it remains in the data structures. > > Fixed by making sure we never free in reject_statements gfc_new_charlen > created structures if old_cl was non-NULL. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > OK.
--- gcc/fortran/symbol.c.jj 2010-11-15 09:28:07.000000000 +0100 +++ gcc/fortran/symbol.c 2010-12-10 12:23:03.000000000 +0100 @@ -3219,19 +3219,29 @@ gfc_new_charlen (gfc_namespace *ns, gfc_ gfc_charlen *cl; cl = gfc_get_charlen (); - /* Put into namespace. */ - cl->next = ns->cl_list; - ns->cl_list = cl; - /* Copy old_cl. */ if (old_cl) { + /* Put into namespace, but don't allow reject_statement + to free it if old_cl is given. */ + gfc_charlen **prev = &ns->cl_list; + cl->next = ns->old_cl_list; + while (*prev != ns->old_cl_list) + prev = &(*prev)->next; + *prev = cl; + ns->old_cl_list = cl; cl->length = gfc_copy_expr (old_cl->length); cl->length_from_typespec = old_cl->length_from_typespec; cl->backend_decl = old_cl->backend_decl; cl->passed_length = old_cl->passed_length; cl->resolved = old_cl->resolved; } + else + { + /* Put into namespace. */ + cl->next = ns->cl_list; + ns->cl_list = cl; + } return cl; } --- gcc/testsuite/gfortran.dg/pr46884.f.jj 2010-12-10 13:59:39.000000000 +0100 +++ gcc/testsuite/gfortran.dg/pr46884.f 2010-12-10 13:59:13.000000000 +0100 @@ -0,0 +1,8 @@ +C PR fortran/46884 +C { dg-do compile } +C { dg-options "" } + SUBROUTINE F + IMPLICIT CHARACTER*12 (C) + CALL G(C1) + CALL H(C1(1:4)) + END