diff mbox series

[Fortran,committed] PR82511: ICE Bad IO basetype (12) on attempted read or write of entire DEC structure

Message ID CAE4aFA=+EawW_MimBsePfg+2+Dej2B-vuiNYm4LaLv9QrfY+tg@mail.gmail.com
State New
Headers show
Series [Fortran,committed] PR82511: ICE Bad IO basetype (12) on attempted read or write of entire DEC structure | expand

Commit Message

Fritz Reese Oct. 16, 2017, 5:48 p.m. UTC
All,

The simple attached patch which fixes PR 82511 has been committed to
trunk as r253791. It regtests on x86_64-redhat-linux-gnu.

The issue was an ICE when a variable containing a BT_UNION (basetype
12) component was given in a I/O list. The patch treats the BT_UNION
component as a derived type variable, thus recursing into its final
components (across all of its MAPs).

---
Fritz Reese
diff mbox series

Patch

From 89ed92f0127b61bc802e43c8f3125f48540d7c27 Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Mon, 16 Oct 2017 13:27:28 -0400
Subject: [PATCH] Treat UNION components as DT comp. in I/O lists.

	PR fortran/82511
	gcc/fortran/
	* trans-io.c (transfer_expr): Treat BT_UNION as BT_DERIVED.

	PR fortran/82511
	gcc/testsuite/gfortran.dg/
	* dec_structure_22.f90: New testcase.
---
 gcc/fortran/trans-io.c                         |  4 +--
 gcc/testsuite/gfortran.dg/dec_structure_22.f90 | 38 ++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_22.f90

diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index 026f9a993d2..f3e1f3e4d09 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -2404,7 +2404,7 @@  transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr,
     case BT_CLASS:
       if (ts->u.derived->components == NULL)
 	return;
-      if (ts->type == BT_DERIVED || ts->type == BT_CLASS)
+      if (gfc_bt_struct (ts->type) || ts->type == BT_CLASS)
 	{
 	  gfc_symbol *derived;
 	  gfc_symbol *dtio_sub = NULL;
@@ -2438,7 +2438,7 @@  transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr,
 	      function = iocall[IOCALL_X_DERIVED];
 	      break;
 	    }
-	  else if (ts->type == BT_DERIVED)
+	  else if (gfc_bt_struct (ts->type))
 	    {
 	      /* Recurse into the elements of the derived type.  */
 	      expr = gfc_evaluate_now (addr_expr, &se->pre);
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_22.f90 b/gcc/testsuite/gfortran.dg/dec_structure_22.f90
new file mode 100644
index 00000000000..ddbee02602a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_22.f90
@@ -0,0 +1,38 @@ 
+      ! { dg-do run }
+      ! { dg-options "-fdec-structure" }
+      !
+      ! PR fortran/82511
+      !
+      ! Verify that structure variables with UNION components
+      ! are accepted in an I/O-list READ.
+      !
+      implicit none
+
+      structure /s/
+        union
+          map
+            character(16) :: c16_1
+          end map
+          map
+            character(16) :: c16_2
+          end map
+        end union
+      end structure
+
+      record /s/ r
+      character(32) :: instr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^"
+
+      r.c16_1 = '                '
+      r.c16_2 = '                '
+      ! The record r shall be treated as if its components are listed:
+      ! read(...) r.c16_1, r.c16_2
+      ! This shall correspond to the formatted read of A16,A16
+      read(instr, '(A16,A16)') r
+
+      ! r.c16_1 and r.c16_2 are in a union, thus share the same memory
+      ! and the first 16 bytes of instr are overwritten
+      if ( r.c16_1 .ne. instr(17:32) .or. r.c16_2 .ne. instr(17:32) ) then
+        call abort()
+      endif
+
+      end
-- 
2.12.2