ICE in [1] is due to an incomplete fix for PR fortran/77327 (r239819,
see [2],[3]). Specifically in interface.c (gfc_compare_derived_types)
I overlooked the case where FL_UNION type symbols could be compared as
equal to FL_STRUCTURE type symbols, which is _never_ correct. The
faulty logic causes a UNION to be considered equal to a STRUCTURE,
thus the union receives the structure's backend declaration. Obviously
everything goes haywire from there.

Attached is the [obvious] fix. Will commit to trunk soon, barring any
concerns from others.

---
Fritz Reese

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77782
[2] https://gcc.gnu.org/ml/fortran/2016-08/msg00144.html
[3] https://gcc.gnu.org/ml/fortran/2016-08/msg00145.html

2016-09-29  Fritz Reese  <fritzore...@gmail.com>

        Fix ICE caused by union types comparing equal to structure types.

        PR fortran/77782
        * gcc/fortran/interface.c (gfc_compare_derived_types): Use
        gfc_compare_union_types to compare union types.

        PR fortran/77782
        * gcc/testsuite/gfortran.dg/dec_structure_16.f90: New testcase.
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 9a19fa7..9d4e5e9 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -589,6 +589,10 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
 
   gcc_assert (derived1 && derived2);
 
+  /* Compare UNION types specially.  */
+  if (derived1->attr.flavor == FL_UNION || derived2->attr.flavor == FL_UNION)
+    return gfc_compare_union_types (derived1, derived2);
+
   /* Special case for comparing derived types across namespaces.  If the
      true names and module names are the same and the module name is
      nonnull, then they are equal.  */
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_16.f90 b/gcc/testsuite/gfortran.dg/dec_structure_16.f90
new file mode 100644
index 0000000..f9b2671
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_16.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure" }
+!
+! PR fortran/77782
+!
+! Test an ICE where a union might be considered equal to a structure,
+! causing the union's backend_decl to be replaced with that of the structure.
+!
+
+program p
+
+structure /s1/
+  union
+    map
+      integer(4) a
+      end map
+    map
+      real(4) b
+    end map
+  end union
+end structure
+
+structure /s2/
+  union ! regression: if this union == s1, we ICE in gfc_get_union_type
+    map
+      integer(2) x, y
+      integer(4) z
+    end map
+  end union
+end structure
+
+record /s1/ r1
+r1.a = 0
+
+end

Reply via email to