I have a patch that exposes this and causes a "miscompile" of gfortran.dg/cray_pointers_2.f90. Reduced testcase: ! { dg-do run } ! { dg-options "-fcray-pointer -fbounds-check" } ! Series of routines for testing a Cray pointer implementation program craytest call ptr5 end program craytest subroutine ptr5 logical :: intne integer :: i integer, parameter :: n = 9 integer itarg1 (n) integer ipte1 (*) pointer(iptr4,ipte1) iptr4 = loc(itarg1) do, i=1,n ipte1(i) = i if (intne(ipte1(i), itarg1(i))) then ! Error #143 call abort() endif end do end subroutine ptr5 ! Separate function calls to break Cray pointer-indifferent optimization logical function intne(ii,jj) integer :: i,j intne = ii.ne.jj if (intne) then write (*,*) ii," doesn't equal ",jj endif end function intne where we can see the following IL created by the FE: ptr5 () { integer(kind=4) i; integer(kind=8) iptr4; integer(kind=4) ipte1[1] [value-expr: *(integer(kind=4)[1] *) iptr4]; integer(kind=4) itarg1[9]; { integer(kind=8) D.1548; D.1548 = (integer(kind=8)) &itarg1; iptr4 = D.1548; } ... ipte1[NON_LVALUE_EXPR <SAVE_EXPR <(integer(kind=8)) i>> + -1] = i; ... if (intne (&ipte1[NON_LVALUE_EXPR <SAVE_EXPR <(integer(kind=8)) i>> + -1], &itarg1[NON_LVALUE_EXPR <SAVE_EXPR <(integer(kind=8)) i>> + -1])) you can clearly see that substituting the value-expr *(integer(kind=4)[1] *) iptr4 for ipte1 will expose an array size of 1 (!) to the middle-end, which it will happily oblige to and optimize &ipte1[i - 1] to &ipte1[0]. If the array size is not known the FE should generate *(integer(kind=4)[] *) iptr4
I think the "1" comes about due to the following. That can either leave that part as is and change it back in in trans*.c via "cp_was_assumed" -- or one removes that part and sees what will break ;-) From decl.c: /* Cray Pointees can be declared as: pointer (ipt, a (n,m,...,*)) By default, this is treated as an AS_ASSUMED_SIZE array. We'll cheat and set a constant bound of 1 for the last dimension, if this is the case. Since there is no bounds-checking for Cray Pointees, this will be okay. */ match gfc_mod_pointee_as (gfc_array_spec *as) { as->cray_pointee = true; /* This will be useful to know later. */ if (as->type == AS_ASSUMED_SIZE) { as->type = AS_EXPLICIT; as->upper[as->rank - 1] = gfc_int_expr (1); as->cp_was_assumed = true; }
What is done for assumed-size arrays such as a(*)?
Created attachment 20083 [details] Lightly tested patch
Accept. (Draft?) patches: - Part 1: http://gcc.gnu.org/ml/fortran/2010-03/msg00061.html - Part 2: http://gcc.gnu.org/ml/fortran/2010-03/msg00062.html
Subject: Bug 43331 Author: burnus Date: Wed Mar 17 09:53:40 2010 New Revision: 157512 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157512 Log: 2010-03-17 Tobias Burnus <burnus@net-b.de> PR fortran/43331 * trans-array.c (gfc_conv_array_index_offset,gfc_conv_array_ref, gfc_conv_ss_startstride): Remove no-longer-needed cp_was_assumed check. * decl.c (gfc_match_derived_decl): Don't mark assumed-size Cray pointees as having explizit size. * expr.c (gfc_check_assign): Remove now unreachable Cray pointee check. * trans-types.c (gfc_is_nodesc_array): Add cp_was_assumed to * assert. (gfc_sym_type): Don't mark Cray pointees as restricted pointers. * resolve.c (resolve_symbol): Handle cp_was_assumed. * trans-decl.c (gfc_trans_deferred_vars): Ditto. (gfc_finish_var_decl): Don't mark Cray pointees as restricted pointers. 2010-03-17 Tobias Burnus <burnus@net-b.de> PR fortran/43331 * gfortran.dg/cray_pointers_1.f90: Update dg-error message. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/decl.c trunk/gcc/fortran/expr.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-types.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/cray_pointers_1.f90
FIXED on the trunk (4.5). Richard: Thanks for the clear bug report! And for making the middle-end smarter with regards to bonds. Actually, will this middle-end change cause problems for inlining such old-style Fortran code as below? real A(100) call sub(A(1), 100) ! Correct syntax: "call sub(A, 100)" subroutine sub(x, n) integer n real x(*) ! Or: "real x(n)" to be slightly more modern x(n) = 5 (I think the code was never valid but one can find it quite often in old code that it passes the first array element to a procedure, which expects an array.)
Subject: Re: Cray pointers generate bogus IL for the middle-end On Wed, 17 Mar 2010, burnus at gcc dot gnu dot org wrote: > ------- Comment #6 from burnus at gcc dot gnu dot org 2010-03-17 10:03 ------- > FIXED on the trunk (4.5). > > Richard: Thanks for the clear bug report! And for making the middle-end smarter > with regards to bonds. > > Actually, will this middle-end change cause problems for inlining such > old-style Fortran code as below? > > real A(100) > call sub(A(1), 100) ! Correct syntax: "call sub(A, 100)" > > subroutine sub(x, n) > integer n > real x(*) ! Or: "real x(n)" to be slightly more modern > x(n) = 5 > > (I think the code was never valid but one can find it quite often in old code > that it passes the first array element to a procedure, which expects an array.) The middle-end should be able to deal with this (well, worst case by refusing to inline). Richard.