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

login
register
mail settings
Submitter Tobias Burnus
Date July 22, 2010, 9:34 a.m.
Message ID <4C4810B9.20608@net-b.de>
Download mbox | patch
Permalink /patch/59554/
State New
Headers show

Comments

Tobias Burnus - July 22, 2010, 9:34 a.m.
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
Daniel Kraft - July 22, 2010, 10:03 a.m.
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

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" } }