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:;