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); }