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

            Bug ID: 90744
           Summary: [9/10 Regression] Bogus length for character
                    temporaries passed to external procedures since
                    r268992
           Product: gcc
           Version: 9.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: trnka at scm dot com
  Target Milestone: ---

The fix for PR87689 in r268992 broke some of our code that passes character
temporaries as actual arguments to external procedures. The length of the
string is not passed correctly, leading to segfaults once the external
procedure touches the string.

To reproduce, compile the following two files (gfortran -g concat-length.f90
convrs.f90) and see a segfault in convrs(). (I couldn't reduce this further.
For example, the seemingly useless "if" in DoTest() is important, convrs() has
to be called from both branches or the issue won't appear. I'd guess it's due
to some CSE/redundancy elimination, but the issue also occurs at -O0.)

external-char-length.f90
------------------------
module StringModule
   implicit none

contains
   function getstr()
      character(:), allocatable :: getstr

      getstr = 'OK'
   end function
end module
module TestModule
   use StringModule
   implicit none

contains
   subroutine DoTest()
      if (.false.) then
         call convrs('A',getstr())
      else
         call convrs('B',getstr())
      end if
   end subroutine
end module
program external_char_length
   use TestModule

   implicit none

   call DoTest()
end program
------------------------

convrs.f90
------------------------
subroutine convrs(quanty,fromto)
   implicit none

   character(*), intent(in) :: quanty,fromto

   write(*,*) fromto
end subroutine
------------------------

Comparing the dumps from a good and bad gfortran, it's evident that "slen.2" is
being passed incorrectly by reference:

--- good-85bbaeac3dd/external-char-length.f90.004t.original    2019-06-04
15:39:28.440490081 +0200
+++ bad-d50eaffb899/external-char-length.f90.004t.original     2019-06-04
15:28:39.410192786 +0200
@@ -51,7 +51,7 @@
     pstr.3 = 0B;
     slen.2 = 0;
     getstr (&pstr.3, &slen.2);
-    convrs (&"B"[1]{lb: 1 sz: 1}, pstr.3, 1, slen.2);
+    convrs (&"B"[1]{lb: 1 sz: 1}, pstr.3, 1, &slen.2);
     __builtin_free ((void *) pstr.3);
   }
   L.3:;

Reply via email to