aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-io.c
diff options
context:
space:
mode:
authorJanus Weil <janus@gcc.gnu.org>2016-12-18 14:22:13 +0100
committerJanus Weil <janus@gcc.gnu.org>2016-12-18 14:22:13 +0100
commit707024b2e8d74c4a810ba7d2bda5ecd6556d2140 (patch)
treeb9d6cf3db49054b6bab44ff447099c387bc054f4 /gcc/fortran/trans-io.c
parent413e859cdf69f402e64da550f6513021eb173fdc (diff)
downloadgcc-707024b2e8d74c4a810ba7d2bda5ecd6556d2140.zip
gcc-707024b2e8d74c4a810ba7d2bda5ecd6556d2140.tar.gz
gcc-707024b2e8d74c4a810ba7d2bda5ecd6556d2140.tar.bz2
re PR fortran/78848 ([OOP] ICE on writing CLASS variable with non-typebound DTIO procedure)
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
Diffstat (limited to 'gcc/fortran/trans-io.c')
-rw-r--r--gcc/fortran/trans-io.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index b60685e..5f9c191 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -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. */