[Bug fortran/88511] New: passing allocatable character through two levels of procedure calls fails

2018-12-15 Thread stephen at soliday dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88511

Bug ID: 88511
   Summary: passing allocatable character through two levels of
procedure calls fails
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: fortran
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stephen at soliday dot com
  Target Milestone: ---

Please see the thread that I started in Stack overflow. Several respondents
have reproduced this problem in 8.2.1 and 9.0.0. In those threads there is
reduced version of code that also reproduces the bug.


I am experiencing an allocation failure when using allocatable character
strings as optional arguments. The problem only occurs when I call through two
levels of procedures. In my actual code ***call get_level1()*** (see below)
represents a call to a list data structure and ***call get_level2()***
represents the list calling the same type of accessor function on one of its
records. I have stripped down an example to the bare minimum that adequately
reproduces the problem.

In the code below when I call ***get_level2*** directly the expected character
string is returned through the optional argument. When I call ***get_level1***
which in turn calls ***get_level2*** allocation of the optional dummy argument
fails. Using gdb I find the allocation attempt to create a character*1635...
when it gets back to the actual argument is obviously has an integer overflow
because it thinks the allocation is character*-283635612...

My actual code has many optional arguments not just one. As a simple example I
added an optional integer argument. This time instead of a segmentation fault I
get a null string.

In the second example the integer argument works regardless of using the
character argument. (I would expect this since no  dynamic allocation is being
performed) The integer's presence has no effect on the character. I have also
tried changing the **intent** to (inout). This does not change the behavior,
though I did not expect it to. [I believe that *intent(out)* causes the actual
argument to deallocate first, and *intent(inout)* retains the actual argument's
allocation state]

call get_level1( NUM=n )  ! works
call get_level1( NUM=n, TEXT=words )  ! fails
call get_level1( TEXT=words ) ! fails

my compile cmd is:

gfortran -Wall -g -std=f2008ts stest1.f08 -o stest

**Environment**

Linux 4.15.0-42-generic #45-Ubuntu SMP x86_64 GNU/Linux
GNU Fortran (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

**Example with one optional argument**

module stest1
  implicit none

  character(:), allocatable :: data

contains

  subroutine get_level2( TEXT )
implicit none
character(:), optional, allocatable, intent(out) :: TEXT

if ( PRESENT( TEXT ) ) then
   TEXT = 'Prefix: ' // data // ' :postfix'
end if

  end subroutine get_level2


  subroutine get_level1( TEXT )
implicit none
character(:), optional, allocatable, intent(out) :: TEXT

call get_level2( TEXT )

  end subroutine get_level1

end module stest1


program main
  use stest1
  implicit none

  character(:), allocatable :: words

  data  = 'Hello Doctor'

  call get_level1( words )

  write(*,100) words

100 format( 'words = [',A,']' )

end program main

**Example with two optional arguments**

module stest2
  implicit none

  character(:), allocatable :: data
  integer   :: count

contains

  subroutine get_level2( TEXT, NUM )
implicit none
character(:), optional, allocatable, intent(out) :: TEXT
integer,  optional,  intent(out) :: NUM

if ( PRESENT( TEXT ) ) then
   TEXT = 'Prefix: ' // data // ' :postfix'
end if

if ( PRESENT( NUM ) ) then
   NUM = count
end if

  end subroutine get_level2


  subroutine get_level1( TEXT, NUM )
implicit none
character(:), optional, allocatable, intent(out) :: TEXT
integer,  optional,  intent(out) :: NUM

call get_level2( NUM=NUM, TEXT=TEXT )

  end subroutine get_level1

end module stest2


program main
  use stest2
  implicit none

  character(:), allocatable :: words
  integer   :: n

  count = 42
  data  = 'Hello Doctor'

  call get_level1( TEXT=words )

  write(*,100) words
  write(*,110) n

100 format( 'words = [',A,']' )
110 format( 'N = [',I0,']' )

end program main

[Bug fortran/88511] passing allocatable character through two levels of procedure calls fails

2018-12-15 Thread stephen at soliday dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88511

--- Comment #1 from Stephen Soliday  ---
One of the respondents in Stack overflow posted this reduced version of my code
that also reproduces the segmentation fault.

program main
  implicit none
  character(:), allocatable :: txt

  call sub1(txt)
  print *, "main ", len(txt), txt  ! prints: main 0 (or throws segfault)

contains
  subroutine sub1(txt)
character(:), allocatable, optional, intent(out) :: txt
call sub2(txt)
print *, "sub1 ", len(txt), txt! prints: sub1 0 (or throws segfault)
  end subroutine sub1
  subroutine sub2(txt)
character(:), allocatable, optional, intent(out) :: txt
if(present(txt)) txt = "message"
print *, "sub2 ", len(txt), txt! prints: sub2 7 message
  end subroutine sub2
end program main

[Bug libfortran/109454] New: Possible memory leak after using random_number

2023-04-08 Thread stephen at soliday dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109454

Bug ID: 109454
   Summary: Possible memory leak after using random_number
   Product: gcc
   Version: 11.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libfortran
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stephen at soliday dot com
  Target Milestone: ---

Simple call to RANDOM_NUMBER leaves 168 bytes still reachable after the process
exits, as indicated by valgrind.

GNU Fortran:   11.3.0
valgrind:  3.18.1
Ubuntu:22.04.2 LTS
Linux Kernel:  5.15.0-69-generic


v- cut here v (rtest.f90)
program main
  use iso_fortran_env
  implicit none

  real(REAL64) :: x

  call random_number(x)

  print *, x

end program main
^- cut here ^

gfortran -o rtest rtest.f90

valgrind --leak-check=full --show-leak-kinds=all regulus/bin/ftest_fuzzy
./rtest

v- cut here -v
==44961== Memcheck, a memory error detector
==44961== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==44961== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==44961== Command: regulus/bin/ftest_fuzzy ./rtest
==44961== 
  0.26639924712129115 
==44961== 
==44961== HEAP SUMMARY:
==44961== in use at exit: 168 bytes in 2 blocks
==44961==   total heap usage: 133 allocs, 131 frees, 112,809 bytes allocated
==44961== 
==44961== 40 bytes in 1 blocks are still reachable in loss record 1 of 2
==44961==at 0x484DA83: calloc (in
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==44961==by 0x6CF8F86: ??? (in
/usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0)
==44961==by 0x6F63F46: _gfortran_random_r8 (in
/usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0)
==44961==by 0x1136DC: __ftest_fuzzy_test_MOD_test03 (ftest_fuzzy.f90:221)
==44961==by 0x116FD1: MAIN__ (ftest_fuzzy.f90:238)
==44961==by 0x11702D: main (ftest_fuzzy.f90:234)
==44961== 
==44961== 128 bytes in 1 blocks are still reachable in loss record 2 of 2
==44961==at 0x484DCD3: realloc (in
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==44961==by 0x70A58AC: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==44961==by 0x70B8114: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==44961==by 0x70A3FE1: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==44961==by 0x400647D: call_init.part.0 (dl-init.c:70)
==44961==by 0x4006567: call_init (dl-init.c:33)
==44961==by 0x4006567: _dl_init (dl-init.c:117)
==44961==by 0x40202E9: ??? (in
/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
==44961==by 0x1: ???
==44961==by 0x1FFF00015A: ???
==44961==by 0x1FFF000172: ???
==44961== 
==44961== LEAK SUMMARY:
==44961==definitely lost: 0 bytes in 0 blocks
==44961==indirectly lost: 0 bytes in 0 blocks
==44961==  possibly lost: 0 bytes in 0 blocks
==44961==still reachable: 168 bytes in 2 blocks
==44961== suppressed: 0 bytes in 0 blocks
==44961== 
==44961== For lists of detected and suppressed errors, rerun with: -s
==44961== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
^- cut here -^