If the first argument to a function is of type "character" (of any length, from what I can tell, including ":" and "*") and the second parameter is both passed by value and optional, the second argument will be identified as "present" even when absent. The following short program reproduces the problem with gfortran 12.2.1: program bugdemo implicit none character :: s integer :: t s = 'a' t = testoptional(s) print*, 'testoptional: ', t contains function testoptional(w, x) result(t) character, intent(in) :: w integer, intent(in), value, optional :: x integer :: t print*, 'present(x) is ', present(x) t = 0 end function testoptional end program bugdemo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! When compiled and run with gfortran 12.2.1, this gives the following output: present(x) is T testoptional: 0 [clearly, the first line should have "F" instead of "T"]
Confirmed. There is an inconsistency either in the generated code for the caller or the callee: integer(kind=4) testoptional (character(kind=1)[1:1] & restrict w, integer(kind=4) x, integer(kind=8) _w, logical(kind=1) _x) vs. t = testoptional (&s, 0, 0, 1); How does the ABI define the ordering of character length and presence flag?
(In reply to anlauf from comment #1) > Confirmed. > > There is an inconsistency either in the generated code for the caller or > the callee: > > integer(kind=4) testoptional (character(kind=1)[1:1] & restrict w, > integer(kind=4) x, integer(kind=8) _w, logical(kind=1) _x) > > vs. > > t = testoptional (&s, 0, 0, 1); > > How does the ABI define the ordering of character length and presence flag? Yep, there's an API issue. If you use character(len=13) :: s the produced code is t = testoptional (&s, 0, 0, 13); so the hidden charlen is tacked on last whereas I think the hidden presence argument is also expected to be last. Likely a counting error in generating the interface.
(In reply to kargl from comment #2) > so the hidden charlen is tacked on last whereas I think the hidden presence > argument is also expected to be last. Likely a counting error in generating > the interface. I've found the code generating the function call in gfc_conv_procedure_call (trans-expr.cc:7680) /* Add the return arguments. */ vec_safe_splice (retargs, arglist); /* Add the hidden present status for optional+value to the arguments. */ vec_safe_splice (retargs, optionalargs); /* Add the hidden string length parameters to the arguments. */ vec_safe_splice (retargs, stringargs); /* We may want to append extra arguments here. This is used e.g. for calls to libgfortran_matmul_??, which need extra information. */ vec_safe_splice (retargs, append_args); We now need the corresponding part on the procedure side.
(In reply to anlauf from comment #3) > We now need the corresponding part on the procedure side. That might be create_function_arglist (trans-decl.cc). There's currently a single hidden_arglist, which needs to be aligned to the caller's side. Is there a public documentation what the ordering should be?
(In reply to anlauf from comment #4) > Is there a public documentation what the ordering should be? It is actually documented for gfortran: https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html The arguments are passed in the following order * Result variable, when the function result is passed by reference * Character length of the function result, if it is a of type CHARACTER and no C binding is used * The arguments in the order in which they appear in the Fortran declaration * The present status for optional arguments with value attribute, which are internally passed by value * The character length and/or coarray token and offset for the first argument which is a CHARACTER or a nonallocatable coarray dummy argument, followed by the hidden arguments of the next dummy argument of such a type So it is create_function_arglist which is broken.
Created attachment 53782 [details] Patch Regtesting the attached patch.
(In reply to anlauf from comment #6) > Created attachment 53782 [details] > Patch > > Regtesting the attached patch. Looks good for the reported issue. However, while working on variations of the testcase, I hit an ICE for: subroutine test3 (w) character, intent(in), value, optional :: w print*, 'present(w) is ', present(w) end subroutine test3 It is not new, though.
(In reply to anlauf from comment #7) > However, while working on variations of the testcase, I hit an ICE for: > > subroutine test3 (w) > character, intent(in), value, optional :: w > print*, 'present(w) is ', present(w) > end subroutine test3 > > It is not new, though. This is now tracked in PR107444.
On Thu, Oct 27, 2022 at 09:11:08PM +0000, anlauf at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107441 > > --- Comment #8 from anlauf at gcc dot gnu.org --- > (In reply to anlauf from comment #7) > > However, while working on variations of the testcase, I hit an ICE for: > > > > subroutine test3 (w) > > character, intent(in), value, optional :: w > > print*, 'present(w) is ', present(w) > > end subroutine test3 > > > > It is not new, though. > > This is now tracked in PR107444. > If no other issues pop up and if this is an old issue, you can probably commit your fix for current issue as you've opened a new bug report. Thanks for pecking away at gfortran bugs.
Submitted: https://gcc.gnu.org/pipermail/fortran/2022-October/058398.html
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>: https://gcc.gnu.org/g:e805adaa283129604a1fb305d0a1cf1e8a90c76e commit r13-3863-ge805adaa283129604a1fb305d0a1cf1e8a90c76e Author: Harald Anlauf <anlauf@gmx.de> Date: Fri Oct 28 21:58:08 2022 +0200 Fortran: ordering of hidden procedure arguments [PR107441] The gfortran ABI specifies the order of given and hidden procedure arguments, where the hidden presence status flags of optional+value scalar arguments shall come before character length, coarray token and offset. Respect that. gcc/fortran/ChangeLog: PR fortran/107441 * trans-decl.cc (create_function_arglist): Adjust the ordering of automatically generated hidden procedure arguments to match the documented ABI for gfortran. * trans-types.cc (gfc_get_function_type): Separate hidden parameters so that the presence flag for optional+value arguments come before string length, coarray token and offset, as required. gcc/testsuite/ChangeLog: PR fortran/107441 * gfortran.dg/coarray/pr107441-caf.f90: New test. * gfortran.dg/optional_absent_6.f90: New test. * gfortran.dg/optional_absent_7.f90: New test.
Fixed on mainline for gcc-13. Closing. Thanks for the report!
*** Bug 91196 has been marked as a duplicate of this bug. ***