From patchwork Fri Jul 23 08:42:20 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Fortran] PR45019 - Fix FE alias analysis for argument association From: Tobias Burnus X-Patchwork-Id: 59745 Message-Id: <4C4955EC.6080205@net-b.de> To: Daniel Kraft Cc: gfortran , gcc patches Date: Fri, 23 Jul 2010 10:42:20 +0200 On 07/22/2010 12:03 PM, Daniel Kraft wrote: > Tobias Burnus wrote: >> 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 [...] Thanks for the review. Committed as Rev. 162410. For 4.4 and 4.5 one needs to remove the "attr.contiguous" part. Additionally, the second part of the test case does not work on 4.4. (Though, that test does not check the patch rather the "restrict" pointer attribute - though both tests are for the same Fortran standard constraint; thus there is some other patch which has not been backported to 4.4.) Tobias PS: For 4.4, see Rev. 162448 and the attachment. Index: gcc/testsuite/ChangeLog =================================================================== --- gcc/testsuite/ChangeLog (revision 162447) +++ gcc/testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2010-07-23 Tobias Burnus + + PR fortran/45019 + * gfortran.dg/aliasing_dummy_5.f90: New. + 2010-07-22 Jakub Jelinek Backport from mainline Index: gcc/testsuite/gfortran.dg/aliasing_dummy_5.f90 =================================================================== --- gcc/testsuite/gfortran.dg/aliasing_dummy_5.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/aliasing_dummy_5.f90 (revision 0) @@ -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) stop '2' ! FIXME: This does not work with GCC 4.4 + 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" } } Index: gcc/fortran/symbol.c =================================================================== --- gcc/fortran/symbol.c (revision 162447) +++ gcc/fortran/symbol.c (working copy) @@ -2673,6 +2673,17 @@ gfc_symbols_could_alias (gfc_symbol *lsy 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.dimension || lsym->as->type == AS_ASSUMED_SHAPE)) + || (rsym->attr.dummy + && (!rsym->attr.dimension + || rsym->as->type == AS_ASSUMED_SHAPE)))) + return 1; + return 0; } Index: gcc/fortran/ChangeLog =================================================================== --- gcc/fortran/ChangeLog (revision 162447) +++ gcc/fortran/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2010-07-23 Tobias Burnus + + PR fortran/45019 + * dependency.c (gfc_check_dependency): Add argument alising check. + * symbol.c (gfc_symbols_could_alias): Add argument alising check. + 2010-07-10 Paul Thomas PR fortran/44582 Index: gcc/fortran/dependency.c =================================================================== --- gcc/fortran/dependency.c (revision 162447) +++ gcc/fortran/dependency.c (working copy) @@ -727,6 +727,19 @@ gfc_check_dependency (gfc_expr *expr1, g /* TODO: -fassume-no-pointer-aliasing */ if (gfc_is_data_pointer (expr1) || gfc_is_data_pointer (expr2)) 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.dimension + || sym2->as->type == AS_ASSUMED_SHAPE)) + || (sym2->attr.dummy + && (!sym2->attr.dimension + || sym2->as->type == AS_ASSUMED_SHAPE)))) + return 1; + } /* Otherwise distinct symbols have no dependencies. */ return 0;