[Bug fortran/93762] Truncation of deferred-length string when passing as optional
kargl at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Apr 10 22:36:24 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762
kargl at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |kargl at gcc dot gnu.org
--- Comment #2 from kargl at gcc dot gnu.org ---
(In reply to Thomas Koenig from comment #1)
> Unfortunately, the test case fails with different ways on
> current trunk:
>
> $ gfortran -g a.f90
> $ ./a.out
> at bot of deepest_call, str is "12345"
>
> Program received signal SIGSEGV: Segmentation fault - invalid memory
> reference.
>
> Backtrace for this error:
> #0 0x7f0a66c3059f in ???
> at
> /usr/src/debug/glibc-2.26-lp151.19.11.1.x86_64/signal/../sysdeps/unix/sysv/
> linux/x86_64/sigaction.c:0
> #1 0x400c65 in __interface_call_m_MOD_interface_call
> at /tmp/a.f90:20
> #2 0x400d99 in MAIN__
> at /tmp/a.f90:32
> #3 0x400f0b in main
> at /tmp/a.f90:25
> Speicherzugriffsfehler (Speicherabzug geschrieben)
>
> (gdb) r a.f90
> Starting program: /tmp/a.out a.f90
> at bot of deepest_call, str is "12345"
>
> Program received signal SIGSEGV, Segmentation fault.
> _gfortran_string_len_trim (s=0x6068d0 "12345", len=<optimized out>) at
> ../../../gcc/libgfortran/intrinsics/string_intrinsics_inc.c:231
> 231 if (*((unsigned long*) (s + i + 1)) != blank_longword)
> (gdb) p s
> $1 = 0x6068d0 "12345"
> (gdb) p i
> $2 = 564082115390472183
>
> Seems like uninitialzed memory for i.
>
> Valgrind confirms this:
>
> $ valgrind ./a.out
> ==5621== Memcheck, a memory error detector
> ==5621== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
> ==5621== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
> ==5621== Command: ./a.out
> ==5621==
> at bot of deepest_call, str is "12345"
> ==5621== Conditional jump or move depends on uninitialised value(s)
> ==5621== at 0x50A29A5: _gfortran_string_len_trim
> (string_intrinsics_inc.c:188)
> ==5621== by 0x50A2A87: _gfortran_string_trim (string_intrinsics_inc.c:168)
> ==5621== by 0x400C65: __interface_call_m_MOD_interface_call (a.f90:20)
> ==5621== by 0x400D99: MAIN__ (a.f90:32)
> ==5621== by 0x400F0B: main (a.f90:25)
>
> Not sure if this ever worked in a released version.
I doubt it ever worked. It seems that the length is not getting
set properly for the returning string. Should this be propagated
up the call change in the hidden string length argument. Here's a
modified testcase where I print out lengths of str.
module deepest_call_m
implicit none
contains
subroutine deepest_call(str)
character(len=:), allocatable, optional :: str
character(len=5) t
t = '12345'
if (present(str)) then
str = t
write(*,*) 'at bot of deepest_call, str is "'//trim(str)//'"'
end if
print *, 'len = ', len(str)
print '(A)', 'Returning from deepest_call'
end subroutine deepest_call
end module deepest_call_m
module interface_call_m
implicit none
contains
subroutine interface_call(str)
use deepest_call_m, only : deepest_call
character(len=:), allocatable, optional :: str
if (present(str)) then
call deepest_call(str)
print *, 'len = ', len(str)
write(*,*) 'at bot of interface_call, str is "'//trim(str)//'"'
end if
end subroutine interface_call
end module interface_call_m
program main
use interface_call_m, only : interface_call
implicit none
character(len=:), allocatable :: str
call interface_call(str)
write(*,*) 'at bot of main, str is "'//trim(str)//'"'
end program main
I get
% gfcx -o z -g a.f90 && ./z
at bot of deepest_call, str is "12345"
len = 5
Returning from deepest_call
len = 134516966
Segmentation fault (core dumped)
len = 5 is in deepest_call and the correct value.
len = 134516966 seems to be a bit too large.
More information about the Gcc-bugs
mailing list