The current gfc_check_dependency check always looked at the pointer
attribute - and assumed the worst, if either the LHS or the RHS was true.
Thus, it claimed that "a" and "b" alias for the following definition:
integer, pointer :: p; integer :: a. However, as "a" has no target (or
pointer) attribute, that's not possible. Additionally, "class(t) :: a"
has internally the "pointer" attribute (but
CLASS_DATA(sym)->attr.class_pointer == 0), however, in the Fortran
sense, "a" is not a pointer and cannot alias.
I do not have a good example for the test case, except for a similar one
as above using "a[i] = p" and looking at the dump; but that requires
patch 3/3 of this series.
Build and regtested on x86-64-gnu-linux. (I do get a failure for
gfortran.dg/graphite/pr42393.f90, but only with -O1 -fgraphite-identity
and also without the patch.)
OK for the trunk?
Tobias
2014-08-27 Tobias Burnus <bur...@net-b.de>
PR fortran/62278
* dependency.c (gfc_check_dependency): Allow for optimizations
in the pointer-alias check.
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index c18482a..1cdd141 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -1269,8 +1269,9 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
/* The interesting cases are when the symbols don't match. */
if (expr1->symtree->n.sym != expr2->symtree->n.sym)
{
+ symbol_attribute attr1, attr2;
gfc_typespec *ts1 = &expr1->symtree->n.sym->ts;
- gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;
+ gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;
/* Return 1 if expr1 and expr2 are equivalenced arrays. */
if (gfc_are_equivalenced_arrays (expr1, expr2))
@@ -1284,9 +1285,13 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
return 0;
}
- /* If either variable is a pointer, assume the worst. */
- /* TODO: -fassume-no-pointer-aliasing */
- if (gfc_is_data_pointer (expr1) || gfc_is_data_pointer (expr2))
+ /* We have to also include target-target as ptr%comp is not a
+ pointer but it still alias with "dt%comp" for "ptr => dt". As
+ subcomponents and array access to pointers retains the target
+ attribute, that's sufficient. */
+ attr1 = gfc_expr_attr (expr1);
+ attr2 = gfc_expr_attr (expr2);
+ if ((attr1.pointer || attr1.target) && (attr2.pointer || attr2.target))
{
if (check_data_pointer_types (expr1, expr2)
&& check_data_pointer_types (expr2, expr1))