+2006-03-16 Roger Sayle <roger@eyesopen.com>
+
+ * gfortran.h (gfc_equiv_info): Add length field.
+ * trans-common.c (copy_equiv_list_to_ns): Set the length field.
+ * dependency.c (gfc_are_equivalenced_arrays): Use both the offset
+ and length fields to determine whether the two equivalenced symbols
+ overlap in memory.
+
2006-03-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/19101
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. */
+ guaranteed to pick up indirect equivalences. We explicitly
+ check for overlap using the offset and length of the equivalence.
+ This function is symmetric.
+ TODO: This function only checks whether the full top-level
+ symbols overlap. An improved implementation could inspect
+ e1->ref and e2->ref to determine whether the actually accessed
+ portions of these variables/arrays potentially overlap. */
int
gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2)
for (s = l->equiv; s; s = s->next)
{
if (s->sym == e1->symtree->n.sym)
- fl1 = s;
+ {
+ fl1 = s;
+ if (fl2)
+ break;
+ }
if (s->sym == e2->symtree->n.sym)
- fl2 = s;
- if (fl1 && fl2 && (fl1->offset > fl2->offset))
+ {
+ fl2 = s;
+ if (fl1)
+ break;
+ }
+ }
+
+ if (s)
+ {
+ /* Can these lengths be zero? */
+ if (fl1->length <= 0 || fl2->length <= 0)
+ return 1;
+ /* These can't overlap if [f11,fl1+length] is before
+ [fl2,fl2+length], or [fl2,fl2+length] is before
+ [fl1,fl1+length], otherwise they do overlap. */
+ if (fl1->offset + fl1->length > fl2->offset
+ && fl2->offset + fl2->length > fl1->offset)
return 1;
}
}
-return 0;
+ return 0;
}
--- /dev/null
+! { dg-do compile }
+! { dg-options "-O2 -fdump-tree-original" }
+ integer :: i(5)
+ real(4) :: x(5)
+ equivalence(x,i)
+
+ i = (/ 1, 0, 3, 5, 0 /)
+ where (i(1:4) .ne. 0)
+ x(2:5) = -42.
+ end where
+ end
+! { dg-final { scan-tree-dump-times "malloc" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }