diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 9d4e5e9..55923a3 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -526,6 +526,7 @@ int gfc_compare_union_types (gfc_symbol *un1, gfc_symbol *un2) { gfc_component *map1, *map2, *cmp1, *cmp2; + gfc_symbol *map1_t, *map2_t; if (un1->attr.flavor != FL_UNION || un2->attr.flavor != FL_UNION) return 0; @@ -541,16 +542,26 @@ gfc_compare_union_types (gfc_symbol *un1, gfc_symbol *un2) we compare the maps sequentially. */ for (;;) { - cmp1 = map1->ts.u.derived->components; - cmp2 = map2->ts.u.derived->components; + map1_t = map1->ts.u.derived; + map2_t = map2->ts.u.derived; + + cmp1 = map1_t->components; + cmp2 = map2_t->components; + + /* Protect against null components. */ + if (map1_t->attr.zero_comp != map2_t->attr.zero_comp) + return 0; + + if (map1_t->attr.zero_comp) + return 1; + for (;;) { /* No two fields will ever point to the same map type unless they are the same component, because one map field is created with its type declaration. Therefore don't worry about recursion here. */ /* TODO: worry about recursion into parent types of the unions? */ - if (compare_components (cmp1, cmp2, - map1->ts.u.derived, map2->ts.u.derived) == 0) + if (compare_components (cmp1, cmp2, map1_t, map2_t) == 0) return 0; cmp1 = cmp1->next; diff --git a/gcc/testsuite/gfortran.dg/dec_union_8.f90 b/gcc/testsuite/gfortran.dg/dec_union_8.f90 new file mode 100644 index 0000000..2d856fc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dec_union_8.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! { dg-options "-fdec-structure" } +! +! PR fortran/77764 +! +! Test an ICE due to a map with zero components. +! + +program p + +structure /s1/ + union + map + end map + map + real :: a = 2.0 + end map + end union +end structure + +end