This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[PATCH, Fortran] Fix ICE due to comparison between UNION components
- From: Fritz Reese <fritzoreese at gmail dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, fortran <fortran at gcc dot gnu dot org>
- Date: Sun, 2 Oct 2016 18:27:51 -0400
- Subject: [PATCH, Fortran] Fix ICE due to comparison between UNION components
- Authentication-results: sourceware.org; auth=none
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 <fritzoreese@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