aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/dependency.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/dependency.c')
-rw-r--r--gcc/fortran/dependency.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 5b0045e..9c6b4f6 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -175,6 +175,45 @@ gfc_is_same_range (gfc_array_ref * ar1, gfc_array_ref * ar2, int n, int def)
}
+/* Return true if the result of reference REF can only be constructed
+ using a temporary array. */
+
+bool
+gfc_ref_needs_temporary_p (gfc_ref *ref)
+{
+ int n;
+ bool subarray_p;
+
+ subarray_p = false;
+ for (; ref; ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ /* Vector dimensions are generally not monotonic and must be
+ handled using a temporary. */
+ if (ref->u.ar.type == AR_SECTION)
+ for (n = 0; n < ref->u.ar.dimen; n++)
+ if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
+ return true;
+
+ subarray_p = true;
+ break;
+
+ case REF_SUBSTRING:
+ /* Within an array reference, character substrings generally
+ need a temporary. Character array strides are expressed as
+ multiples of the element size (consistent with other array
+ types), not in characters. */
+ return subarray_p;
+
+ case REF_COMPONENT:
+ break;
+ }
+
+ return false;
+}
+
+
/* Dependency checking for direct function return by reference.
Returns true if the arguments of the function depend on the
destination. This is considerably less conservative than other
@@ -185,9 +224,7 @@ int
gfc_check_fncall_dependency (gfc_expr * dest, gfc_expr * fncall)
{
gfc_actual_arglist *actual;
- gfc_ref *ref;
gfc_expr *expr;
- int n;
gcc_assert (dest->expr_type == EXPR_VARIABLE
&& fncall->expr_type == EXPR_FUNCTION);
@@ -205,31 +242,8 @@ gfc_check_fncall_dependency (gfc_expr * dest, gfc_expr * fncall)
switch (expr->expr_type)
{
case EXPR_VARIABLE:
- if (expr->rank > 1)
- {
- /* This is an array section. */
- for (ref = expr->ref; ref; ref = ref->next)
- {
- if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
- break;
- }
- gcc_assert (ref);
- /* AR_FULL can't contain vector subscripts. */
- if (ref->u.ar.type == AR_SECTION)
- {
- for (n = 0; n < ref->u.ar.dimen; n++)
- {
- if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
- break;
- }
- /* Vector subscript array sections will be copied to a
- temporary. */
- if (n != ref->u.ar.dimen)
- continue;
- }
- }
-
- if (gfc_check_dependency (dest, actual->expr, NULL, 0))
+ if (!gfc_ref_needs_temporary_p (expr->ref)
+ && gfc_check_dependency (dest, expr, NULL, 0))
return 1;
break;