[PATCH] fortran/30207 -- Fix a WHERE and array section problem
Steve Kargl
sgk@troutmask.apl.washington.edu
Thu Dec 14 07:46:00 GMT 2006
The attached patch has been built and tested on i386-*-freebsd.
It short circuits the dependency checking on arrays in a WHERE
statement (and maybe others) when an array section is present.
That is,
integer :: z(4) = (/1,1,-1,-1/)
where (z < 0) z(:) = 1
will lead to an ICE gfc_dep_resolver. The short circuiting causes
the allocation of temporary array to hold the mask from the z < 0
conditional. Note the -fdump-tree-original code generated from the
above is quite ugly in comparison to
integer :: z(4) = (/1,1,-1,-1/)
where (z < 0) z = 1
There may be a better way to fix this problem. Thus, the CC to
Roger, who wrote gfc_dep_resolver.
2006-12-13 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/30207
* fortran/dependency.c (gfc_dep_resolver): Short circuit dependency
checking with an array section.
* gfortran.fortran-torture/execute/where21.f90: New test.
--
Steve
-------------- next part --------------
Index: gcc/testsuite/gfortran.fortran-torture/execute/where21.f90
===================================================================
--- gcc/testsuite/gfortran.fortran-torture/execute/where21.f90 (revision 0)
+++ gcc/testsuite/gfortran.fortran-torture/execute/where21.f90 (revision 0)
@@ -0,0 +1,9 @@
+! { dg-do run }
+! Test fix for PR fortran/30207.
+program a
+ implicit none
+ integer, parameter :: i(4) = (/ 1, 1, 1, 1 /)
+ integer :: z(4) = (/ 1, 1, -1, -1 /)
+ where(z < 0) z(:) = 1
+ if (any(z /= i)) call abort
+end program a
Index: gcc/fortran/dependency.c
===================================================================
--- gcc/fortran/dependency.c (revision 119854)
+++ gcc/fortran/dependency.c (working copy)
@@ -1128,7 +1128,7 @@ gfc_dep_resolver (gfc_ref * lref, gfc_re
while (lref && rref)
{
/* We're resolving from the same base symbol, so both refs should be
- the same type. We traverse the reference chain intil we find ranges
+ the same type. We traverse the reference chain until we find ranges
that are not equal. */
gcc_assert (lref->type == rref->type);
switch (lref->type)
@@ -1163,6 +1163,15 @@ gfc_dep_resolver (gfc_ref * lref, gfc_re
this_dep = gfc_check_element_vs_section (rref, lref, n);
else
{
+ /* Short circuit "where(z < 0) z(:) = 1" where the array
+ section notation is causing the problem. */
+ if (lref->u.ar.dimen_type[n] == DIMEN_RANGE
+ && rref->u.ar.dimen_type[n] == 0)
+ {
+ this_dep = GFC_DEP_OVERLAP;
+ break;
+ }
+
gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
&& lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
this_dep = gfc_check_element_vs_element (rref, lref, n);
More information about the Fortran
mailing list