summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-16 21:44:56 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-16 21:44:56 +0000
commit0952470405408223ce8e403dff6ca202ee884f02 (patch)
tree006e315b53333153d3725f16068e58e8c481291f
parent89af5f35b1bd462a3b9bb7ba96660f47a8e9df61 (diff)
downloadgcc-0952470405408223ce8e403dff6ca202ee884f02.tar.gz
2013-11-16 Paul Thomas <pault@gcc.gnu.org>
PR fortran/58771 * trans-io.c (transfer_expr): If the backend_decl for a derived type is missing, build it with gfc_typenode_for_spec. 2013-11-16 Paul Thomas <pault@gcc.gnu.org> PR fortran/58771 * gfortran.dg/derived_external_function_1.f90 : New test git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_8-branch@204907 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-io.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/derived_external_function_1.f9027
4 files changed, 56 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 58bbc7fdd8c..6be3c238ad7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-16 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/58771
+ * trans-io.c (transfer_expr): If the backend_decl for a derived
+ type is missing, build it with gfc_typenode_for_spec.
+
2013-11-05 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/58989
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index 9394810f01f..a11453d082d 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -243,16 +243,16 @@ gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
/* The code to generate the error. */
gfc_start_block (&block);
-
+
arg1 = gfc_build_addr_expr (NULL_TREE, var);
-
+
arg2 = build_int_cst (integer_type_node, error_code),
-
+
asprintf (&message, "%s", _(msgid));
arg3 = gfc_build_addr_expr (pchar_type_node,
gfc_build_localized_cstring_const (message));
free (message);
-
+
tmp = build_call_expr_loc (input_location,
gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
@@ -521,7 +521,7 @@ set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
"Unit number in I/O statement too small",
&se.pre);
-
+
/* UNIT numbers should be less than the max. */
val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
@@ -1000,7 +1000,7 @@ gfc_trans_open (gfc_code * code)
if (p->convert)
mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
p->convert);
-
+
if (p->newunit)
mask |= set_parameter_ref (&block, &post_block, var, IOPARM_open_newunit,
p->newunit);
@@ -1234,7 +1234,7 @@ gfc_trans_inquire (gfc_code * code)
{
mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
p->exist);
-
+
if (p->unit && !p->iostat)
{
p->iostat = create_dummy_iostat ();
@@ -1322,7 +1322,7 @@ gfc_trans_inquire (gfc_code * code)
if (p->pad)
mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
p->pad);
-
+
if (p->convert)
mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
p->convert);
@@ -1547,7 +1547,7 @@ transfer_namelist_element (stmtblock_t * block, const char * var_name,
tree dtype;
tree dt_parm_addr;
tree decl = NULL_TREE;
- int n_dim;
+ int n_dim;
int itype;
int rank = 0;
@@ -2032,7 +2032,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
if (gfc_notification_std (GFC_STD_GNU) != SILENT)
{
gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
- ts->u.derived->name, code != NULL ? &(code->loc) :
+ ts->u.derived->name, code != NULL ? &(code->loc) :
&gfc_current_locus);
return;
}
@@ -2041,7 +2041,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
ts->kind = ts->u.derived->ts.kind;
ts->f90_type = ts->u.derived->ts.f90_type;
}
-
+
kind = ts->kind;
function = NULL;
arg2 = NULL;
@@ -2123,7 +2123,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
function = iocall[IOCALL_X_CHARACTER_WIDE];
else
function = iocall[IOCALL_X_CHARACTER_WIDE_WRITE];
-
+
tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
tmp = build_call_expr_loc (input_location,
function, 4, tmp, addr_expr, arg2, arg3);
@@ -2158,6 +2158,12 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
expr = build_fold_indirect_ref_loc (input_location,
expr);
+ /* Make sure that the derived type has been built. An external
+ function, if only referenced in an io statement requires this
+ check (see PR58771). */
+ if (ts->u.derived->backend_decl == NULL_TREE)
+ tmp = gfc_typenode_for_spec (ts);
+
for (c = ts->u.derived->components; c; c = c->next)
{
field = c->backend_decl;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e761544084a..2bf5c698339 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-16 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/58771
+ * gfortran.dg/derived_external_function_1.f90 : New test
+
2013-11-14 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline
diff --git a/gcc/testsuite/gfortran.dg/derived_external_function_1.f90 b/gcc/testsuite/gfortran.dg/derived_external_function_1.f90
new file mode 100644
index 00000000000..7421c4c0f22
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_external_function_1.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR fortran/58771
+!
+! Contributed by Vittorio Secca <zeccav@gmail.com>
+!
+! ICEd on the write statement with f() because the derived type backend
+! declaration not built.
+!
+module m
+ type t
+ integer(4) g
+ end type
+end
+
+type(t) function f() result(ff)
+ use m
+ ff%g = 42
+end
+
+ use m
+ character (20) :: line1, line2
+ type(t) f
+ write (line1, *) f()
+ write (line2, *) 42_4
+ if (line1 .ne. line2) call abort
+end