http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46325

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P4
                 CC|                            |jakub at gcc dot gnu.org
          Component|middle-end                  |fortran

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2010-11-10 
16:07:32 UTC ---
The problem is that we choose to put A.19 and parm.22 into the same partition:

;; Function char_initialiser (MAIN__)

Partition 0: size 15 align 16
        x, offset 0
Partition 5: size 48 align 16
        parm.22, offset 0
        A.19, offset 0
Partition 3: size 48 align 16
        atmp.18, offset 0
Partition 4: size 48 align 16
        ptrtemp.16, offset 0
Partition 1: size 48 align 16
        y, offset 0

But A.19 is live until the end of function:
  D.1613_7 = (void * restrict) &A.19[0][1]{lb: 1 sz: 1};
  atmp.18.data = D.1613_7;
...
  D.1596_13 = &atmp.18;
...
  pfoo (&ptrtemp.16, 5, D.1596_13, 5);
  y = ptrtemp.16;
  parm.22.dtype = 369;
  parm.22.dim[0].lbound = 1;
  parm.22.dim[0].ubound = 3;
  parm.22.dim[0].stride = 1;
  parm.22.data = &x[0];
  parm.22.offset = -1;
  afoo (&y, &parm.22, 5, 5);
  return;
and thus when it is shared with parm.22 it is overwritten.

I'm using a reduced testcase:
program char_initialiser
  character*5, dimension(3) :: x
  character*5, dimension(:), pointer :: y
  x=(/"is Ja","ne Fo","nda  "/)
  y => pfoo ((/"is Ja","ne Fo","nda  "/))
  call afoo (y, x)
contains
  subroutine afoo(ch1, ch2)
     character*(*), dimension(:) :: ch1, ch2
     if (any(ch1 /= ch2)) call abort ()
  end subroutine afoo
  function pfoo(ch2)
     character*5, dimension(:), target  :: ch2
     character*5, dimension(:), pointer :: pfoo
     pfoo => ch2
  end function pfoo
end program

If this is actually valid Fortran (i.e. the lifetime of
(/"is Ja","ne Fo","nda  "/)
when passed as actual argument to pfoo doesn't end with the return from pfoo),
then it would be a Fortran FE bug - A.19 which is used as the data area for the
atmp.18 temporary whose address is passed to pfoo, is declared in a BLOCK which
starts before atmp.18 definition but doesn't end at the end of function, but
right after y = ptrtemp.16; stmt (and parm.22 correctly starts living just for
the setup of afoo parameters and lives over the actual afoo call.  Thus there
is nothing wrong on the expansion side that it decided to coalesce the two
variables, it is either a FE bug or invalid testcase.

-fdump-tree-origin contains:

...
  {
    integer(kind=8) D.1598;
    character(kind=1)[0:][1:5] * ifm.21;
    struct array1_unknown * D.1596;
    character(kind=1) A.19[3][1:5];
    struct array1_unknown atmp.18;
    static character(kind=1)[1:5] * A.17[3] = {&"is Ja"[1]{lb: 1 sz: 1}, &"ne
Fo"[1]{lb: 1 sz: 1}, &"nda  "[1]{lb: 1 sz: 1}};
    struct array1_unknown ptrtemp.16;

    atmp.18.dtype = 369;
    atmp.18.dim[0].stride = 1;
    atmp.18.dim[0].lbound = 0;
    atmp.18.dim[0].ubound = 2;
    atmp.18.data = (void * restrict) &A.19;
    atmp.18.offset = 0;
    {
      integer(kind=8) S.20;

      S.20 = 0;
      while (1)
        {
          if (S.20 > 2) goto L.5;
          __builtin_memmove ((void *) &(*(character(kind=1)[3][1:5] * restrict)
atmp.18.data)[S.20], (void *) A.17[S.20], 5);
          S.20 = S.20 + 1;
        }
      L.5:;
    }
    D.1596 = &atmp.18;
    ifm.21 = (character(kind=1)[0:][1:5] *) D.1596->data;
    D.1598 = (D.1596->dim[0].ubound - D.1596->dim[0].lbound) + 1;
    pfoo (&ptrtemp.16, 5, D.1596, 5);
    y = ptrtemp.16;
  }
  {
    struct array1_unknown parm.22;

    parm.22.dtype = 369;
    parm.22.dim[0].lbound = 1;
    parm.22.dim[0].ubound = 3;
    parm.22.dim[0].stride = 1;
    parm.22.data = (void *) &x[0];
    parm.22.offset = -1;
    afoo (&y, &parm.22, 5, 5);
  }

Reply via email to