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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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