re PR fortran/78848 ([OOP] ICE on writing CLASS variable with non-typebound DTIO...
authorJanus Weil <janus@gcc.gnu.org>
Sun, 18 Dec 2016 13:22:13 +0000 (14:22 +0100)
committerJanus Weil <janus@gcc.gnu.org>
Sun, 18 Dec 2016 13:22:13 +0000 (14:22 +0100)
2016-12-18  Janus Weil  <janus@gcc.gnu.org>

PR fortran/78848
* trans-io.c (get_dtio_proc): Generate non-typebound DTIO call for class
variables, if no typebound DTIO procedure is available.

2016-12-18  Janus Weil  <janus@gcc.gnu.org>

PR fortran/78848
* gfortran.dg/dtio_22.f90: New test.

From-SVN: r243784

gcc/fortran/ChangeLog
gcc/fortran/trans-io.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dtio_22.f90 [new file with mode: 0644]

index 693d51fd5ba07fc8b5a8278d6d65e6f4a437ca7e..d718a3fbbaf0122a56e7a98f904b8c2be188c030 100644 (file)
@@ -1,3 +1,9 @@
+2016-12-18  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/78848
+       * trans-io.c (get_dtio_proc): Generate non-typebound DTIO call for class
+       variables, if no typebound DTIO procedure is available.
+
 2016-12-18  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/78592
index b60685ee1572053f6b0097224b3f4a091c60c911..5f9c191968576e7b3378c3af1d8494ff3a7730fd 100644 (file)
@@ -2180,41 +2180,39 @@ get_dtio_proc (gfc_typespec * ts, gfc_code * code, gfc_symbol **dtio_sub)
       formatted = true;
     }
 
-  if (ts->type == BT_DERIVED)
+  if (ts->type == BT_CLASS)
+    derived = ts->u.derived->components->ts.u.derived;
+  else
+    derived = ts->u.derived;
+
+  gfc_symtree *tb_io_st = gfc_find_typebound_dtio_proc (derived,
+                                                 last_dt == WRITE, formatted);
+  if (ts->type == BT_CLASS && tb_io_st)
+    {
+      // polymorphic DTIO call  (based on the dynamic type)
+      gfc_se se;
+      gfc_expr *expr = gfc_find_and_cut_at_last_class_ref (code->expr1);
+      gfc_add_vptr_component (expr);
+      gfc_add_component_ref (expr,
+                            tb_io_st->n.tb->u.generic->specific_st->name);
+      *dtio_sub = tb_io_st->n.tb->u.generic->specific->u.specific->n.sym;
+      gfc_init_se (&se, NULL);
+      se.want_pointer = 1;
+      gfc_conv_expr (&se, expr);
+      gfc_free_expr (expr);
+      return se.expr;
+    }
+  else
     {
-      derived = ts->u.derived;
+      // non-polymorphic DTIO call (based on the declared type)
       *dtio_sub = gfc_find_specific_dtio_proc (derived, last_dt == WRITE,
                                              formatted);
 
       if (*dtio_sub)
        return gfc_build_addr_expr (NULL, gfc_get_symbol_decl (*dtio_sub));
     }
-  else if (ts->type == BT_CLASS)
-    {
-      gfc_symtree *tb_io_st;
-
-      derived = ts->u.derived->components->ts.u.derived;
-      tb_io_st = gfc_find_typebound_dtio_proc (derived,
-                                              last_dt == WRITE, formatted);
-      if (tb_io_st)
-       {
-         gfc_se se;
-         gfc_expr *expr = gfc_find_and_cut_at_last_class_ref (code->expr1);
-         gfc_add_vptr_component (expr);
-         gfc_add_component_ref (expr,
-                                tb_io_st->n.tb->u.generic->specific_st->name);
-         *dtio_sub = tb_io_st->n.tb->u.generic->specific->u.specific->n.sym;
-         gfc_init_se (&se, NULL);
-         se.want_pointer = 1;
-         gfc_conv_expr (&se, expr);
-         gfc_free_expr (expr);
-         return se.expr;
-       }
-    }
-
 
   return NULL_TREE;
-
 }
 
 /* Generate the call for a scalar transfer node.  */
index 6583316bbf4f7fd5c8294ad187daaf4d4634f18b..7b91b7b86b0601c82ee2be715eef1d7f77b6dfc3 100644 (file)
@@ -1,3 +1,8 @@
+2016-12-18  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/78848
+       * gfortran.dg/dtio_22.f90: New test.
+
 2016-12-18  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/78592
diff --git a/gcc/testsuite/gfortran.dg/dtio_22.f90 b/gcc/testsuite/gfortran.dg/dtio_22.f90
new file mode 100644 (file)
index 0000000..f39450c
--- /dev/null
@@ -0,0 +1,33 @@
+! { dg-do run }
+!
+! PR 78848: [OOP] ICE on writing CLASS variable with non-typebound DTIO procedure
+!
+! Contributed by Mikael Morin <morin-mikael@orange.fr>
+
+module m
+  type :: t
+    integer :: i = 123
+  end type
+  interface write(formatted)
+    procedure wf
+  end interface
+contains
+  subroutine wf(this, unit, b, c, iostat, iomsg)
+    class(t), intent(in) :: this
+    integer, intent(in) :: unit
+    character, intent(in) :: b
+    integer, intent(in) :: c(:)
+    integer, intent(out) :: iostat
+    character, intent(inout) :: iomsg
+    write (unit, "(i3)", IOSTAT=iostat, IOMSG=iomsg) this%i
+  end subroutine
+end
+
+program p
+  use m
+  character(3) :: buffer
+  class(t), allocatable :: z
+  allocate(z)
+  write(buffer,"(DT)") z
+  if (buffer /= "123") call abort()
+end