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
From 89ed92f0127b61bc802e43c8f3125f48540d7c27 Mon Sep 17 00:00:00 2001 From: Fritz Reese <fritzore...@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