Hi all, here is another rather simple patch for an ice-on-invalid problem. The patch consists of three hunks, out of which the last two actually fix two ICEs that occurred on the different test cases: The second one removes an assert which seems unnecessary to me (since there are anyway other cases where tb becomes NULL), and the third checks whether the symtree exists already before creating a new one.
The first hunk is just cosmetics / code simplification, using gfc_get_tbp_symtree instead of the (equivalent) combination of gfc_find_symtree and gfc_new_symtree. [Btw, speaking of gfc_get_tbp_symtree: Can anyone tell me by chance why it is necessary to nullify 'result->n.tb' on a newly-created symtree?] The patch regtests cleanly on x86_64-linux-gnu. Ok for trunk? Cheers, Janus 2016-11-11 Janus Weil <ja...@gcc.gnu.org> PR fortran/77501 * decl.c (gfc_match_decl_type_spec): Use gfc_get_tbp_symtree, fix indentation. (gfc_match_generic): Remove an unnecessary assert. Use gfc_get_tbp_symtree to avoid ICE. 2016-11-11 Janus Weil <ja...@gcc.gnu.org> PR fortran/77501 * gfortran.dg/typebound_generic_16.f90: New test.
Index: gcc/fortran/decl.c =================================================================== --- gcc/fortran/decl.c (Revision 242066) +++ gcc/fortran/decl.c (Arbeitskopie) @@ -3198,13 +3198,11 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int im upe->attr.zero_comp = 1; if (!gfc_add_flavor (&upe->attr, FL_DERIVED, NULL, &gfc_current_locus)) - return MATCH_ERROR; - } + return MATCH_ERROR; + } else { - st = gfc_find_symtree (gfc_current_ns->sym_root, "STAR"); - if (st == NULL) - st = gfc_new_symtree (&gfc_current_ns->sym_root, "STAR"); + st = gfc_get_tbp_symtree (&gfc_current_ns->sym_root, "STAR"); st->n.sym = upe; upe->refs++; } @@ -9731,14 +9729,7 @@ gfc_match_generic (void) gfc_symtree* st; st = gfc_find_symtree (is_op ? ns->tb_uop_root : ns->tb_sym_root, name); - if (st) - { - tb = st->n.tb; - gcc_assert (tb); - } - else - tb = NULL; - + tb = st ? st->n.tb : NULL; break; } @@ -9783,10 +9774,8 @@ gfc_match_generic (void) case INTERFACE_USER_OP: { const bool is_op = (op_type == INTERFACE_USER_OP); - gfc_symtree* st; - - st = gfc_new_symtree (is_op ? &ns->tb_uop_root : &ns->tb_sym_root, - name); + gfc_symtree* st = gfc_get_tbp_symtree (is_op ? &ns->tb_uop_root : + &ns->tb_sym_root, name); gcc_assert (st); st->n.tb = tb;
! { dg-do compile } ! ! PR 77501: [F03] ICE in gfc_match_generic, at fortran/decl.c:9429 ! ! Contributed by Gerhard Steinmetz <gerhard.steinmetz.fort...@t-online.de> module m1 type t contains generic :: f => g ! { dg-error "must target a specific binding" } generic :: g => h ! { dg-error "Undefined specific binding" } end type end module m2 type t contains generic :: f => g ! { dg-error "must target a specific binding" } generic :: g => f ! { dg-error "Undefined specific binding" } end type end