aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gmx.de>2015-07-06 12:26:12 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2015-07-06 12:26:12 +0200
commitc16126ac1815c23771abc76d7daa30662dc31379 (patch)
treec52a82843f3c1435cfba1b2ed903bdb4e71476cb /gcc/fortran/trans-expr.c
parentc8ba649886633947106b28f1ebf43b3b0d86be6c (diff)
downloadgcc-c16126ac1815c23771abc76d7daa30662dc31379.zip
gcc-c16126ac1815c23771abc76d7daa30662dc31379.tar.gz
gcc-c16126ac1815c23771abc76d7daa30662dc31379.tar.bz2
re PR fortran/58586 (ICE with derived type with allocatable component passed by value)
gcc/testsuite/ChangeLog: 2015-07-06 Andre Vehreschild <vehre@gmx.de> PR fortran/58586 * gfortran.dg/alloc_comp_class_3.f03: New test. * gfortran.dg/alloc_comp_class_4.f03: New test. gcc/fortran/ChangeLog: 2015-07-06 Andre Vehreschild <vehre@gmx.de> PR fortran/58586 * resolve.c (resolve_symbol): Non-private functions in modules with allocatable or pointer components are marked referenced now. Furthermore is the default init especially for those components now done in gfc_conf_procedure_call preventing duplicate code. * trans-decl.c (gfc_generate_function_code): Generate a fake result decl for functions returning an object with allocatable components and initialize them. * trans-expr.c (gfc_conv_procedure_call): For value typed trees use the tree without indirect ref. And for non-decl trees add a temporary variable to prevent evaluating the tree multiple times (prevent multiple function evaluations). * trans.h: Made gfc_trans_structure_assign () protoype available, which is now needed by trans-decl.c:gfc_generate_ function_code(), too. From-SVN: r225447
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 7747a67..195f7a4 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -1465,7 +1465,6 @@ realloc_lhs_warning (bt type, bool array, locus *where)
}
-static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init);
static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
gfc_expr *);
@@ -5340,8 +5339,19 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
&& e->expr_type != EXPR_VARIABLE && !e->rank)
{
int parm_rank;
- tmp = build_fold_indirect_ref_loc (input_location,
- parmse.expr);
+ /* It is known the e returns a structure type with at least one
+ allocatable component. When e is a function, ensure that the
+ function is called once only by using a temporary variable. */
+ if (!DECL_P (parmse.expr))
+ parmse.expr = gfc_evaluate_now_loc (input_location,
+ parmse.expr, &se->pre);
+
+ if (fsym && fsym->attr.value)
+ tmp = parmse.expr;
+ else
+ tmp = build_fold_indirect_ref_loc (input_location,
+ parmse.expr);
+
parm_rank = e->rank;
switch (parm_kind)
{
@@ -7158,7 +7168,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
/* Assign a derived type constructor to a variable. */
-static tree
+tree
gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init)
{
gfc_constructor *c;
@@ -7471,7 +7481,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
if (expr->ts.type == BT_CHARACTER
&& expr->expr_type != EXPR_FUNCTION)
gfc_conv_string_parameter (se);
- else
+ else
se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
return;