diff mbox

[Fortran] PR45019 - Fix FE alias analysis for argument association

Message ID 4C4810B9.20608@net-b.de
State New
Headers show

Commit Message

Tobias Burnus July 22, 2010, 9:34 a.m. UTC
This fixes an alias analysis bug for argument association; if two
variables are both TARGET and (at least) one is a dummy (plus some other
constraints) then the variables might alias.

gfortran and five other compilers get this wrong, only three of my nine
tested compilers give the correct result: Sun, NAG and Cray.

The test case only checks the gfc_symbols_could_alias code path; I think
it should be possible to find a test case, which goes through
gfc_check_dependency, but I could not find one. (I have not tried
extensively.) If someone has (or wants to create) such a test case, I
would like to add it to the test suite.

Build and regtested on x86-64-linux.
OK for the trunk, 4.5 and 4.4? Does anyone care about 4.3?

Quotes from the standard and links to the j3 and c.l.f discussion, see PR.

Tobias

Comments

Daniel Kraft July 22, 2010, 10:03 a.m. UTC | #1
Tobias Burnus wrote:
> This fixes an alias analysis bug for argument association; if two
> variables are both TARGET and (at least) one is a dummy (plus some other
> constraints) then the variables might alias.
> 
> gfortran and five other compilers get this wrong, only three of my nine
> tested compilers give the correct result: Sun, NAG and Cray.
> 
> The test case only checks the gfc_symbols_could_alias code path; I think
> it should be possible to find a test case, which goes through
> gfc_check_dependency, but I could not find one. (I have not tried
> extensively.) If someone has (or wants to create) such a test case, I
> would like to add it to the test suite.
> 
> Build and regtested on x86-64-linux.
> OK for the trunk, 4.5 and 4.4? Does anyone care about 4.3?

As discussed on IRC, the patch is ok if you change

+		       && (sym1->attr.dimension
+		           || sym2->as->type == AS_ASSUMED_SHAPE))
+		      || (sym2->attr.dummy && !sym2->attr.contiguous
+			  && (sym2->attr.dimension

such that we have !sym1->attr.dimension and !sym2->attr.dimension here.

Yours,
Daniel
diff mbox

Patch

2010-07-22  Tobias Burnus  <burnus@net-b.de>

	PR fortran/45019
	* dependency.c (gfc_check_dependency): Add argument alising check.
	* symbol.c (gfc_symbols_could_alias): Add argument alising check.

2010-07-22  Tobias Burnus  <burnus@net-b.de>

	PR fortran/45019
	* gfortran.dg/aliasing_dummy_5.f90: New.

diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 083058d..22a8ddc 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -807,6 +807,19 @@  gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
 
 	      return 1;
 	    }
+	  else
+	    {
+	      gfc_symbol *sym1 = expr1->symtree->n.sym;
+	      gfc_symbol *sym2 = expr2->symtree->n.sym;
+	      if (sym1->attr.target && sym2->attr.target
+		  && ((sym1->attr.dummy && !sym1->attr.contiguous
+		       && (sym1->attr.dimension
+		           || sym2->as->type == AS_ASSUMED_SHAPE))
+		      || (sym2->attr.dummy && !sym2->attr.contiguous
+			  && (sym2->attr.dimension
+			      || sym2->as->type == AS_ASSUMED_SHAPE))))
+		return 1;
+	    }
 
 	  /* Otherwise distinct symbols have no dependencies.  */
 	  return 0;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index df6ada9..c12ea23 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -2811,6 +2811,17 @@  gfc_symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym)
   if (lsym->attr.allocatable && rsym->attr.pointer)
     return 1;
 
+  /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
+     and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
+     checked above.  */
+  if (lsym->attr.target && rsym->attr.target
+      && ((lsym->attr.dummy && !lsym->attr.contiguous
+	   && (!lsym->attr.dimension || lsym->as->type == AS_ASSUMED_SHAPE))
+	  || (rsym->attr.dummy && !rsym->attr.contiguous
+	      && (!rsym->attr.dimension
+		  || rsym->as->type == AS_ASSUMED_SHAPE))))
+    return 1;
+
   return 0;
 }
 
--- /dev/null	2010-07-22 07:40:18.459359409 +0200
+++ gcc/testsuite/gfortran.dg/aliasing_dummy_5.f90	2010-07-22 10:52:35.000000000 +0200
@@ -0,0 +1,55 @@ 
+! { dg-do run }
+! 
+! PR fortran/45019
+!
+! Check that the compiler knows that
+! "arg" and "arr" can alias.
+!
+MODULE m
+  IMPLICIT NONE
+  INTEGER, TARGET :: arr(3)
+CONTAINS
+  SUBROUTINE foobar (arg)
+    INTEGER, TARGET :: arg(:)
+    arr(2:3) = arg(1:2)
+  END SUBROUTINE foobar
+END MODULE m
+
+PROGRAM main
+  USE m
+  IMPLICIT NONE
+  arr = (/ 1, 2, 3 /)
+  CALL bar(arr)
+  if (any (arr /= (/ 1, 1, 2 /))) call abort()
+  CALL test()
+contains
+  subroutine bar(x)
+    INTEGER, TARGET :: x(:)
+    CALL foobar (x)
+  end subroutine bar
+END PROGRAM main
+
+MODULE m2
+  IMPLICIT NONE
+  INTEGER, TARGET :: arr(3)
+CONTAINS
+   SUBROUTINE foobar (arg)
+    INTEGER, TARGET :: arg(:)
+    arr(1) = 5
+    arg(1) = 6
+    if (arr(1) == 5) call abort()
+  END SUBROUTINE foobar
+END MODULE m2
+subroutine test
+  USE m2
+  IMPLICIT NONE
+  arr = (/ 1, 2, 3 /)
+  CALL bar(arr)
+contains
+   subroutine bar(x)
+    INTEGER, TARGET :: x(:)
+    CALL foobar (x)
+  end subroutine bar
+END subroutine test
+
+! { dg-final { cleanup-modules "m m2" } }