diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2006-03-01 22:24:19 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2006-03-01 22:24:19 +0000 |
commit | 61321991ff5f055015750ddf36444705b9921464 (patch) | |
tree | 1fb7018901bd09ec73d55b0ccf66775cd2947e62 /gcc/fortran/dependency.c | |
parent | 8acb1b3d1c6369349372f74e815db2375ea8e0c5 (diff) | |
download | gcc-61321991ff5f055015750ddf36444705b9921464.zip gcc-61321991ff5f055015750ddf36444705b9921464.tar.gz gcc-61321991ff5f055015750ddf36444705b9921464.tar.bz2 |
re PR fortran/26393 (ICE with function returning variable lenght array)
2006-03-01 Paul Thomas <pault@gcc.gnu.org>
* iresolve.c (gfc_resolve_dot_product): Remove any difference in
treatment of logical types.
* trans-intrinsic.c (gfc_conv_intrinsic_dot_product): New function.
PR fortran/26393
* trans-decl.c (gfc_get_symbol_decl): Extend condition that symbols
must be referenced to include unreferenced symbols in an interface
body.
PR fortran/20938
* trans-array.c (gfc_conv_resolve_dependencies): Add call to
gfc_are_equivalenced_arrays.
* symbol.c (gfc_free_equiv_infos, gfc_free_equiv_lists): New
functions. (gfc_free_namespace): Call them.
* trans-common.c (copy_equiv_list_to_ns): New function.
(add_equivalences): Call it.
* gfortran.h: Add equiv_lists to gfc_namespace and define
gfc_equiv_list and gfc_equiv_info.
* dependency.c (gfc_are_equivalenced_arrays): New function.
(gfc_check_dependency): Call it.
* dependency.h: Prototype for gfc_are_equivalenced_arrays.
2006-03-01 Paul Thomas <pault@gcc.gnu.org>
* gfortran.dg/logical_dot_product.f90: New test.
PR fortran/26393
* gfortran.dg/used_interface_ref.f90: New test.
PR fortran/20938
* gfortran.dg/dependency_2.f90: New test.
* gfortran.fortran-torture/execute/where17.f90: New test.
* gfortran.fortran-torture/execute/where18.f90: New test.
* gfortran.fortran-torture/execute/where19.f90: New test.
* gfortran.fortran-torture/execute/where20.f90: New test.
From-SVN: r111616
Diffstat (limited to 'gcc/fortran/dependency.c')
-rw-r--r-- | gcc/fortran/dependency.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index 96da3c31e4..f764873 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -359,6 +359,51 @@ gfc_check_fncall_dependency (gfc_expr * other, sym_intent intent, } +/* Return 1 if e1 and e2 are equivalenced arrays, either + directly or indirectly; ie. equivalence (a,b) for a and b + or equivalence (a,c),(b,c). This function uses the equiv_ + lists, generated in trans-common(add_equivalences), that are + guaranteed to pick up indirect equivalences. A rudimentary + use is made of the offset to ensure that cases where the + source elements are moved down to the destination are not + identified as dependencies. */ + +int +gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2) +{ + gfc_equiv_list *l; + gfc_equiv_info *s, *fl1, *fl2; + + gcc_assert (e1->expr_type == EXPR_VARIABLE + && e2->expr_type == EXPR_VARIABLE); + + if (!e1->symtree->n.sym->attr.in_equivalence + || !e2->symtree->n.sym->attr.in_equivalence + || !e1->rank + || !e2->rank) + return 0; + + /* Go through the equiv_lists and return 1 if the variables + e1 and e2 are members of the same group and satisfy the + requirement on their relative offsets. */ + for (l = gfc_current_ns->equiv_lists; l; l = l->next) + { + fl1 = NULL; + fl2 = NULL; + for (s = l->equiv; s; s = s->next) + { + if (s->sym == e1->symtree->n.sym) + fl1 = s; + if (s->sym == e2->symtree->n.sym) + fl2 = s; + if (fl1 && fl2 && (fl1->offset > fl2->offset)) + return 1; + } + } +return 0; +} + + /* Return true if the statement body redefines the condition. Returns true if expr2 depends on expr1. expr1 should be a single term suitable for the lhs of an assignment. The IDENTICAL flag indicates @@ -405,6 +450,10 @@ gfc_check_dependency (gfc_expr * expr1, gfc_expr * expr2, bool identical) return 1; } + /* Return 1 if expr1 and expr2 are equivalenced arrays. */ + if (gfc_are_equivalenced_arrays (expr1, expr2)) + return 1; + if (expr1->symtree->n.sym != expr2->symtree->n.sym) return 0; |