This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/71623] [5/6/7 Regression] Segfault when allocating deferred-length characters to size of a pointer


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]