#2123 gfortran segfault on writing real128 array

OTHER
unread
nobody
Bug
none
Unknown
False
2013-11-11
2013-10-30
No

I am using the windows binaries of gcc 4.8.1 in a Windows7 x86 machine.
Running a program compiled by gfortran, I cannot "write" a variable which contains an array of real(kind=real128). Scalars seem to work right.
I got this behavior when running this simple program:

1
2
3
4
5
6
program main
   use iso_fortran_env
   real(real128), dimension(2) :: a
   a = (/0., 1./)
   write(*,*) a
end program

It compiles, but get segfault at runtime.

>gfortran main.txt -o main    #successfully compiles!
>main                         #runtime error!

Program received signal SIGSEGV: Segmentation Fault - invalid memory reference.

Backtrace for this error:
#0 ffffffff

Same error is obtained if I:

  • change real(real128) to real(16) in line 03
  • change line 04 to a = (/0._real128, 1._real128)
  • change line 04 to a = real((/0., 1./), kind=real128)
  • declare a variable "b", assign b = a and try to write "b"
  • try to write the value of a pointer pointing to a
  • make variable "a" PARAMETER, SAVE, TARGET or ALLOCATABLE

More weird is that the program successfully run if I:

  • change line 05 to write(,) a(1)
  • change line 05 to write(,) (/0._real128, 1._real128/)
  • change line 05 to write(,) 2*a or any other expression whose result IS NOT a direct reference to "a" or any other variable with real128 array.
  • put a write statement with a value or scalar variable of kind=real128 anywhere in the program's body, no matter if before, after or even inside the write statement of line 05
  • change real(real128) to any other real kind in line 03
  • make "a" scalar

The dump file created when compiling with -fdump-tree-original is:

MAIN__ ()
{
  real(kind=16) a[2];

  {
    static real(kind=16) A.0[2] = {0.0, 1.0e+0};

    (void) (MEM[(c_char * {ref-all})&a] = MEM[(c_char * {ref-all})&A.0]);
    {
      struct __st_parameter_dt dt_parm.1;

      dt_parm.1.common.filename = &"main.f90"[1]{lb: 1 sz: 1};

      dt_parm.1.common.line = 5;
      dt_parm.1.common.flags = 128;
      dt_parm.1.common.unit = 6;
      _gfortran_st_write (&dt_parm.1);
      {
        struct array1_real(kind=16) parm.2;

        parm.2.dtype = 1049;

        parm.2.dim[0].lbound = 1;
        parm.2.dim[0].ubound = 2;
        parm.2.dim[0].stride = 1;
        parm.2.data = (void *) &a[0];
        parm.2.offset = -1;
        _gfortran_transfer_array_write (&dt_parm.1, &parm.2, 16, 0);

      }
      _gfortran_st_write_done (&dt_parm.1);
    }
  }
}

main (integer(kind=4) argc, character(kind=1) * * argv)
{
  static integer(kind=4) options.3[7] = {68, 1023, 0, 0, 1, 1, 0};

  _gfortran_set_args (argc, argv);
  _gfortran_set_options (7, &options.3[0]);
  MAIN__ ();
  return 0;
}

And debugging with gdb shows the following backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
#0  0x00000000 in ?? ()
#1  0x0042d4c3 in output_float_FMT_G_16 (comp_d=<optimized out>, 
    zero_flag=<optimized out>, sign_bit=<optimized out>, 

    size=<optimized out>, buffer=<optimized out>, m=<optimized out>, 
    f=0x22fb6c, dtp=<optimized out>)
    at ../../../gcc-4.8.1-mingw/libgfortran/io/write_float.def:1112
#2  write_float (dtp=dtp@entry=0x22fcf8, f=f@entry=0x22fbbc, 

    source=source@entry=0x22fe70 "", len=len@entry=16, comp_d=comp_d@entry=1)
    at ../../../gcc-4.8.1-mingw/libgfortran/io/write_float.def:1259
#3  0x0041f61f in __gfortrani_write_real (dtp=dtp@entry=0x22fcf8, 

    source=source@entry=0x22fe70 "", length=length@entry=16)
    at ../../../gcc-4.8.1-mingw/libgfortran/io/write.c:1470
#4  0x00419b84 in list_formatted_write_scalar (size=16, kind=16, p=0x22fe70, 
    type=BT_REAL, dtp=0x22fcf8)

    at ../../../gcc-4.8.1-mingw/libgfortran/io/write.c:1571
#5  __gfortrani_list_formatted_write (dtp=0x22fcf8, type=BT_REAL, p=0x22fe70, 
    kind=16, size=16, nelems=2)
    at ../../../gcc-4.8.1-mingw/libgfortran/io/write.c:1599

#6  0x00416dfb in __gfortran_transfer_array (dtp=0x22fcf8, desc=0x22fe58, 
    kind=16, charlen=<optimized out>)
    at ../../../gcc-4.8.1-mingw/libgfortran/io/transfer.c:2170
#7  0x0040170d in MAIN__ ()

#8  0x00401756 in main ()

My specs are:

>ld -v
GNU ld (GNU Binutils) 2.23.52.20130702

>gcc -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/gcc/bin/../libexec/gcc/i686-pc-mingw32/4.8.1/lto-wrapper.
exe
Target: i686-pc-mingw32
Configured with: ../gcc-4.8.1-mingw/configure --host=i686-pc-mingw32 --build=x86
_64-unknown-linux-gnu --target=i686-pc-mingw32 --prefix=/home/gfortran/gcc-home/
binary/mingw32/native/x86_32/gcc/4.8.1 --with-gcc --with-gnu-as --with-gnu-ld --
with-cloog=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/cloog --with-gmp
=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfor
tran/gcc-home/binary/mingw32/native/x86_32/mpfr --with-mpc=/home/gfortran/gcc-ho
me/binary/mingw32/native/x86_32/mpc --with-isl=/home/gfortran/gcc-home/binary/mi
ngw32/native/x86_32/isl --enable-cloog-backend=isl --with-sysroot=/home/gfortran
/gcc-home/binary/mingw32/cross/x86_32/gcc/4.8.1 --disable-shared --disable-nls -
-disable-tls --disable-win32-registry --enable-build-with-cxx --enable-libquadma
th-support --enable-libquadmath --enable-languages=c,c++,fortran --enable-libgom
p --enable-threads=win32 --enable-lto --enable-static --enable-shared=lto-plugin
 --enable-plugins --enable-ld=yes
Thread model: win32
gcc version 4.8.1 (GCC)

I have an open bug report in gcc bugzilla but they say this is probably a platform specific issue with MingW.

I agree, once that I've tested the same program on two linux machines: a x86 ubuntu with gfortran 4.8.1 and a x64 xubuntu with gfortran 4.7.3. Both worked and run properly.

I've also tested on a win8 x86 machine, with gfortran 4.8.0 and it worked too. I don't remember where did I get gfortran for that machine, but I think it was not from Equation Solution.

Discussion