This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/71623] [5/6/7 Regression] Segfault when allocating deferred-length characters to size of a pointer
- From: "zed.three at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 24 Jun 2016 10:28:58 +0000
- Subject: [Bug fortran/71623] [5/6/7 Regression] Segfault when allocating deferred-length characters to size of a pointer
- Auto-submitted: auto-generated
- References: <bug-71623-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71623
--- Comment #3 from zed.three at gmail dot com ---
Changing the pointer to an allocatable array results in the same behaviour:
$ cat allocate_size_mvce.f90
program allocatemvce
implicit none
character(len=:), allocatable :: string
integer, dimension(4), target :: array = [1,2,3,4]
integer, dimension(:), allocatable :: array_alloc
integer :: alloc_size
allocate(array_alloc(size(array)))
allocate(character(len=size(array_alloc))::string)
! The following works:
! alloc_size = size(array_alloc)
! allocate(character(len=alloc_size)::string)
end program allocatemvce
---
In both cases, using -fdump-tree-original to see the IR reveals the
uninitialised variable:
1) For gfortran-4.8, we have something like this:
D.1892 = &array_ptr;
D.1893 = (integer(kind=4)) MAX_EXPR <(D.1892->dim[0].ubound -
D.1892->dim[0].lbound) + 1, 0>;
...
D.1894 = (unsigned long) D.1893;
string = (character(kind=1)[1:.string] *) __builtin_malloc (MAX_EXPR
<D.1894, 1>);
2) Whereas for gfortran-6, we get:
struct array1_integer(kind=4) * D.3395;
...
D.3396 = (unsigned long) (integer(kind=4)) MAX_EXPR
<(D.3395->dim[0].ubound - D.3395->dim[0].lbound) + 1, 0>;
string = (character(kind=1)[1:.string] *) __builtin_malloc (MAX_EXPR
<D.3396, 1>);
and D.3395 is never assigned to.
---
When using "product(shape)", as in Gerhard's example, examining the IR shows
that product(shape(array_ptr)) is never calculated in gfortran-6:
1) For gfortran-4.8, we can see:
_gfortran_shape_4 (&atmp.1, D.1893);
{
integer(kind=8) S.3;
S.3 = 0;
while (1)
{
if (S.3 > 0) goto L.1;
val.0 = (*(integer(kind=4)[1] * restrict) atmp.1.data)[S.3] *
val.0;
S.3 = S.3 + 1;
}
L.1:;
}
which is clearly calculating product(shape(array_ptr))
2) For gfortran-6, nothing like that appears at all, and __builtin_malloc is
called with val.0 uninitialised.
---
Replacing "size(array_ptr)" in the original example with "mysize(array_ptr)",
which is defined as
integer function mysize(ptr)
integer, dimension(:), pointer :: ptr
mysize = size(ptr)
end function mysize
This results in the correct behaviour. In the IR for 6, we essentially get
string = (character(kind=1)[1:.string] *) __builtin_malloc (MAX_EXPR
<(unsigned long) mysize (&array_ptr), 1>);
---
Finally, if we replace "size(array_ptr)" with "size(array)", the IR is
string = (character(kind=1)[1:.string] *) __builtin_malloc (4);
and no intermediate variables are generated (i.e. it directly uses the value of
size(array)).
---
My best guess then is that in gfortran > 5 calls to intrinsics are being elided
in allocating deferred-len characters. That's just a guess though. I'm
currently trying to get my bearings in the gfortran source code to understand
what's going on.