All,

The attached fixes an[other] ICE in the comparison between UNIONs.
This time the ICE is due to a BT_UNION component comparing itself to a
BT_DERIVED component, thus considering their FL_STRUCT and FL_UNION
typenodes to be equal. This is very similar to PR fortran/77782,
except it is an error in the comparison of _components_ from
gfc_compare_types, instead of an error comparing the _type symbols_
from gfc_compare_derived. The patch makes sure that BT_UNION compared
to anything other than BT_UNION is _not_ equal, while still comparing
two union components with gfc_compare_union_types.

Will commit soon with no complaints. Maybe this patch will finally get
type comparison right for unions.

---
Fritz Reese

2016-10-02  Fritz Reese  <fritzore...@gmail.com>

        Fix ICE due to comparison between UNION components.

        * gcc/fortran/interface.c (gfc_compare_types): Don't compare BT_UNION
        components until we know they're both UNIONs.

        * gcc/testsuite/gfortran.dg/dec_union_9.f90: New testcase.
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 04ad0e2..441cc00 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -694,13 +694,14 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
       && (ts1->u.derived->attr.sequence || ts1->u.derived->attr.is_bind_c))
     return 1;
 
-  if (ts1->type == BT_UNION && ts2->type == BT_UNION)
-    return gfc_compare_union_types (ts1->u.derived, ts2->u.derived);
-
   if (ts1->type != ts2->type
-      && ((!gfc_bt_struct (ts1->type) && ts1->type != BT_CLASS)
-	  || (!gfc_bt_struct (ts2->type) && ts2->type != BT_CLASS)))
+      && ((ts1->type != BT_DERIVED && ts1->type != BT_CLASS)
+	  || (ts2->type != BT_DERIVED && ts2->type != BT_CLASS)))
     return 0;
+
+  if (ts1->type == BT_UNION)
+    return gfc_compare_union_types (ts1->u.derived, ts2->u.derived);
+
   if (ts1->type != BT_DERIVED && ts1->type != BT_CLASS)
     return (ts1->kind == ts2->kind);
 
diff --git a/gcc/testsuite/gfortran.dg/dec_union_9.f90 b/gcc/testsuite/gfortran.dg/dec_union_9.f90
new file mode 100644
index 0000000..2cb38fc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_9.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure" }
+!
+! Test a regression where union components could compare equal to structure/map
+! components, causing an ICE in gfc_conv_component_ref.
+!
+
+implicit none
+
+structure /s1/
+  integer(4) i
+end structure
+
+structure /s2/
+  union
+    map
+      record /s1/ r
+    end map
+  end union
+end structure
+
+record /s2/ x
+
+x.r.i = 0
+
+end

Reply via email to