summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authormikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-05 21:41:15 +0000
committermikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-05 21:41:15 +0000
commit3a2545a18b36242908d5498ef7bd9e7a8aa96a10 (patch)
tree6b50b567f3e7b484d1a22fbe37c2dcf74d0ad824 /gcc/fortran/trans-array.c
parent66feb54cdf22a430c0b228314b1a13899c225ce7 (diff)
downloadgcc-3a2545a18b36242908d5498ef7bd9e7a8aa96a10.tar.gz
Fix fortran scalar elemental dependency mishandling
PR fortran/66089 gcc/fortran/ * trans-expr.c (expr_is_variable, gfc_expr_is_variable): Rename the former to the latter and make it non-static. Update callers. * gfortran.h (gfc_expr_is_variable): New declaration. (struct gfc_ss_info): Add field needs_temporary. * trans-array.c (gfc_scalar_elemental_arg_saved_as_argument): Tighten the condition on aggregate expressions with a check that the expression is a variable and doesn't need a temporary. (gfc_conv_resolve_dependency): Add intermediary reference variable. Set the needs_temporary field. gcc/testsuite/ * gfortran.dg/elemental_dependency_6.f90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233188 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r--gcc/fortran/trans-array.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index eeb688c9b91..2ff283312b6 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -2464,10 +2464,12 @@ gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info * ss_info)
return true;
/* If the expression is a data reference of aggregate type,
+ and the data reference is not used on the left hand side,
avoid a copy by saving a reference to the content. */
- if (ss_info->expr->expr_type == EXPR_VARIABLE
+ if (!ss_info->data.scalar.needs_temporary
&& (ss_info->expr->ts.type == BT_DERIVED
- || ss_info->expr->ts.type == BT_CLASS))
+ || ss_info->expr->ts.type == BT_CLASS)
+ && gfc_expr_is_variable (ss_info->expr))
return true;
/* Otherwise the expression is evaluated to a temporary variable before the
@@ -4461,6 +4463,7 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
gfc_ss *ss;
gfc_ref *lref;
gfc_ref *rref;
+ gfc_ss_info *ss_info;
gfc_expr *dest_expr;
gfc_expr *ss_expr;
int nDepend = 0;
@@ -4471,15 +4474,16 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
{
- ss_expr = ss->info->expr;
+ ss_info = ss->info;
+ ss_expr = ss_info->expr;
- if (ss->info->array_outer_dependency)
+ if (ss_info->array_outer_dependency)
{
nDepend = 1;
break;
}
- if (ss->info->type != GFC_SS_SECTION)
+ if (ss_info->type != GFC_SS_SECTION)
{
if (flag_realloc_lhs
&& dest_expr != ss_expr
@@ -4494,6 +4498,10 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
nDepend = gfc_check_dependency (dest_expr, ss_expr, false);
+ if (ss_info->type == GFC_SS_REFERENCE
+ && gfc_check_dependency (dest_expr, ss_expr, false))
+ ss_info->data.scalar.needs_temporary = 1;
+
continue;
}