diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-12-13 12:11:22 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-12-13 12:11:22 +0100 |
commit | 7d7ff3a1c8615f9e6adee9ec84fe42cc1b3597c7 (patch) | |
tree | bc7d9ff53a3fe86e895b052668ef9f569e629789 /gcc/fortran/symbol.c | |
parent | f436d2ff9523eb271a4528a5f7a680cc8ec6f6a7 (diff) | |
download | gcc-7d7ff3a1c8615f9e6adee9ec84fe42cc1b3597c7.zip gcc-7d7ff3a1c8615f9e6adee9ec84fe42cc1b3597c7.tar.gz gcc-7d7ff3a1c8615f9e6adee9ec84fe42cc1b3597c7.tar.bz2 |
re PR fortran/46884 (Use of charlen after free)
PR fortran/46884
* symbol.c (gfc_new_charlen): If old_cl is non-NULL, put it
at the ns->old_cl_list spot in the chain rather than at
ns->cl_list.
* gfortran.dg/pr46884.f: New test.
From-SVN: r167742
Diffstat (limited to 'gcc/fortran/symbol.c')
-rw-r--r-- | gcc/fortran/symbol.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 05c6235..283bfce 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -3219,19 +3219,29 @@ gfc_new_charlen (gfc_namespace *ns, gfc_charlen *old_cl) 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; } |