From patchwork Thu Jul 22 09:34:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 59554 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3B594B70B9 for ; Thu, 22 Jul 2010 19:35:03 +1000 (EST) Received: (qmail 16951 invoked by alias); 22 Jul 2010 09:35:00 -0000 Received: (qmail 16932 invoked by uid 22791); 22 Jul 2010 09:34:58 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mx01.qsc.de (HELO mx01.qsc.de) (213.148.129.14) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 22 Jul 2010 09:34:53 +0000 Received: from [192.168.178.22] (port-92-204-52-63.dynamic.qsc.de [92.204.52.63]) by mx01.qsc.de (Postfix) with ESMTP id 1C40B3D863; Thu, 22 Jul 2010 11:34:50 +0200 (CEST) Message-ID: <4C4810B9.20608@net-b.de> Date: Thu, 22 Jul 2010 11:34:49 +0200 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100520 SUSE/3.0.5 Thunderbird/3.0.5 MIME-Version: 1.0 To: gfortran , gcc patches Subject: [Patch, Fortran] PR45019 - Fix FE alias analysis for argument association Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 2010-07-22 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-22 Tobias Burnus 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" } }