public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
@ 2020-04-10 16:49 ` tkoenig at gcc dot gnu.org
  2020-04-10 22:36 ` kargl at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: tkoenig at gcc dot gnu.org @ 2020-04-10 16:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

Thomas Koenig <tkoenig at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2020-04-10
                 CC|                            |tkoenig at gcc dot gnu.org

--- Comment #1 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
  2020-04-10 16:49 ` [Bug fortran/93762] Truncation of deferred-length string when passing as optional tkoenig at gcc dot gnu.org
@ 2020-04-10 22:36 ` kargl at gcc dot gnu.org
  2020-04-10 23:10 ` sgk at troutmask dot apl.washington.edu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-04-10 22:36 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
  2020-04-10 16:49 ` [Bug fortran/93762] Truncation of deferred-length string when passing as optional tkoenig at gcc dot gnu.org
  2020-04-10 22:36 ` kargl at gcc dot gnu.org
@ 2020-04-10 23:10 ` sgk at troutmask dot apl.washington.edu
  2021-03-12 22:57 ` neil.n.carlson at gmail dot com
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2020-04-10 23:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

--- Comment #3 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
Here's a better testcasei, which removes IO statement, which
makes it easier to read -fdump-tree-original.

module deepest_call_m
   implicit none
   contains
      subroutine deepest_call(str)
         character(len=:), allocatable, intent(out), optional :: str
         if (present(str)) then
            str = '12345'
            if (len(str) /= 5) stop 1
         end if
      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, intent(out), optional :: str
         if (present(str)) then
            call deepest_call(str)
            if (len(str) /= 5) stop 2
         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)
   if (len(str) /= 5) stop 3
end program main

Here's the -fdump-tree-original where I have removed
inconsequential code and re-ordered to help with thinking.
Comments are in-lined.

MAIN__ ()
{
  integer(kind=4) .str;
  character(kind=1)[1:.str] * str;

  str = 0B;
  interface_call (&str, &.str);  /* .str is not set to some value. */ 
}

interface_call (character(kind=1)[1:*_str] * * str, integer(kind=4) * _str)
{
  if (str != 0B)
    {
      {

        /* This is not good.  *_str has the value of .str from MAIN,
           which wasn't set. */

        character(kind=1)[1:*_str] * *D.3819;
        integer(kind=4) D.3820;

        /* Remove freeing from intent(out) attribute. */

        D.3819 = str != 0B ? str : 0B;
        D.3820 = str != 0B ? *_str : 0;

        /* Here D.3820 is 0. */
        deepest_call (D.3819, &D.3820);

        /* *_str should be set to D.3820, but isn't. */
      }
    }
}

deepest_call (character(kind=1)[1:*_str] * * str, integer(kind=4) * _str)
{
  if (str != 0B)
    {
      {
        integer(kind=4) D.3808;
        integer(kind=4) D.3809;

        /* Handle intent(out) and/or re-allocation on assign. */

        /* Set *_str to 5, which is the desired length. */
        *_str = 5;
        D.3808 = *_str;
        if (D.3808 > 0)
          {
             /* Copy '12345' into str. */
          }
      }
    }
}

So, yep!  The string length is not propagated up the call chain.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2020-04-10 23:10 ` sgk at troutmask dot apl.washington.edu
@ 2021-03-12 22:57 ` neil.n.carlson at gmail dot com
  2023-12-02 14:15 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: neil.n.carlson at gmail dot com @ 2021-03-12 22:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

--- Comment #4 from Neil Carlson <neil.n.carlson at gmail dot com> ---
It would be great if somebody possessing the necessary skills could invest the
time to fix this. For me this is bug breaks a common usage pattern of including
optional stat, errmsg arguments to procedure interfaces.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
                   ` (3 preceding siblings ...)
  2021-03-12 22:57 ` neil.n.carlson at gmail dot com
@ 2023-12-02 14:15 ` cvs-commit at gcc dot gnu.org
  2023-12-10 20:14 ` cvs-commit at gcc dot gnu.org
  2023-12-10 20:16 ` anlauf at gcc dot gnu.org
  6 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-12-02 14:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:27ce74fa23c93c1189c301993cd19ea766e6bdb5

commit r14-6081-g27ce74fa23c93c1189c301993cd19ea766e6bdb5
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Fri Dec 1 22:44:30 2023 +0100

    Fortran: deferred-length character optional dummy arguments
[PR93762,PR100651]

    gcc/fortran/ChangeLog:

            PR fortran/93762
            PR fortran/100651
            * trans-array.cc (gfc_trans_deferred_array): Add presence check
            for optional deferred-length character dummy arguments.
            * trans-expr.cc (gfc_conv_missing_dummy): The character length for
            deferred-length dummy arguments is passed by reference, so that
            its value can be returned.  Adjust handling for optional dummies.

    gcc/testsuite/ChangeLog:

            PR fortran/93762
            PR fortran/100651
            * gfortran.dg/optional_deferred_char_1.f90: New test.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
                   ` (4 preceding siblings ...)
  2023-12-02 14:15 ` cvs-commit at gcc dot gnu.org
@ 2023-12-10 20:14 ` cvs-commit at gcc dot gnu.org
  2023-12-10 20:16 ` anlauf at gcc dot gnu.org
  6 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-12-10 20:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Harald Anlauf
<anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:7a2f4af9b1b12d8b1f1b4cf4ddb812f2a48ce9ff

commit r13-8142-g7a2f4af9b1b12d8b1f1b4cf4ddb812f2a48ce9ff
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Fri Dec 1 22:44:30 2023 +0100

    Fortran: deferred-length character optional dummy arguments
[PR93762,PR100651]

    gcc/fortran/ChangeLog:

            PR fortran/93762
            PR fortran/100651
            * trans-array.cc (gfc_trans_deferred_array): Add presence check
            for optional deferred-length character dummy arguments.
            * trans-expr.cc (gfc_conv_missing_dummy): The character length for
            deferred-length dummy arguments is passed by reference, so that
            its value can be returned.  Adjust handling for optional dummies.

    gcc/testsuite/ChangeLog:

            PR fortran/93762
            PR fortran/100651
            * gfortran.dg/optional_deferred_char_1.f90: New test.

    (cherry picked from commit 27ce74fa23c93c1189c301993cd19ea766e6bdb5)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug fortran/93762] Truncation of deferred-length string when passing as optional
       [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
                   ` (5 preceding siblings ...)
  2023-12-10 20:14 ` cvs-commit at gcc dot gnu.org
@ 2023-12-10 20:16 ` anlauf at gcc dot gnu.org
  6 siblings, 0 replies; 7+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-12-10 20:16 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93762

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
   Target Milestone|---                         |13.3
             Status|NEW                         |RESOLVED
                 CC|                            |anlauf at gcc dot gnu.org
         Resolution|---                         |FIXED

--- Comment #7 from anlauf at gcc dot gnu.org ---
Fixed on mainline for gcc-14, and on 13-branch.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-12-10 20:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <bug-93762-4@http.gcc.gnu.org/bugzilla/>
2020-04-10 16:49 ` [Bug fortran/93762] Truncation of deferred-length string when passing as optional tkoenig at gcc dot gnu.org
2020-04-10 22:36 ` kargl at gcc dot gnu.org
2020-04-10 23:10 ` sgk at troutmask dot apl.washington.edu
2021-03-12 22:57 ` neil.n.carlson at gmail dot com
2023-12-02 14:15 ` cvs-commit at gcc dot gnu.org
2023-12-10 20:14 ` cvs-commit at gcc dot gnu.org
2023-12-10 20:16 ` anlauf at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).