From 705628c89faa1135ed9a446b84e831bbead6095a Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Fri, 28 Oct 2022 21:58:08 +0200 Subject: [PATCH] Fortran: ordering of hidden procedure arguments [PR107441] 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. The present status for optional+value arguments is passed before character length and coarray token and offset. 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. --- gcc/fortran/trans-decl.cc | 8 ++- .../gfortran.dg/coarray/pr107441-caf.f90 | 27 +++++++++ .../gfortran.dg/optional_absent_6.f90 | 60 +++++++++++++++++++ .../gfortran.dg/optional_absent_7.f90 | 30 ++++++++++ 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90 create mode 100644 gcc/testsuite/gfortran.dg/optional_absent_6.f90 create mode 100644 gcc/testsuite/gfortran.dg/optional_absent_7.f90 diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 63515b9072a..64b35f054e5 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -2508,7 +2508,7 @@ create_function_arglist (gfc_symbol * sym) tree fndecl; gfc_formal_arglist *f; tree typelist, hidden_typelist; - tree arglist, hidden_arglist; + tree arglist, hidden_arglist, optval_arglist; tree type; tree parm; @@ -2518,6 +2518,7 @@ create_function_arglist (gfc_symbol * sym) the new FUNCTION_DECL node. */ arglist = NULL_TREE; hidden_arglist = NULL_TREE; + optval_arglist = NULL_TREE; typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); if (sym->attr.entry_master) @@ -2712,7 +2713,7 @@ create_function_arglist (gfc_symbol * sym) PARM_DECL, get_identifier (name), boolean_type_node); - hidden_arglist = chainon (hidden_arglist, tmp); + optval_arglist = chainon (optval_arglist, tmp); DECL_CONTEXT (tmp) = fndecl; DECL_ARTIFICIAL (tmp) = 1; DECL_ARG_TYPE (tmp) = boolean_type_node; @@ -2863,6 +2864,9 @@ create_function_arglist (gfc_symbol * sym) typelist = TREE_CHAIN (typelist); } + /* Add hidden present status for optional+value arguments. */ + arglist = chainon (arglist, optval_arglist); + /* Add the hidden string length parameters, unless the procedure is bind(C). */ if (!sym->attr.is_bind_c) diff --git a/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90 b/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90 new file mode 100644 index 00000000000..23b2242e217 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray/pr107441-caf.f90 @@ -0,0 +1,27 @@ +! { dg-do run } +! +! PR fortran/107441 +! Check that with -fcoarray=lib, coarray metadata arguments are passed +! in the right order to procedures. +! +! Contributed by M.Morin + +program p + integer :: ci[*] + ci = 17 + call s(1, ci, "abcd") +contains + subroutine s(ra, ca, c) + integer :: ra, ca[*] + character(*) :: c + ca[1] = 13 + if (ra /= 1) stop 1 + if (this_image() == 1) then + if (ca /= 13) stop 2 + else + if (ca /= 17) stop 3 + end if + if (len(c) /= 4) stop 4 + if (c /= "abcd") stop 5 + end subroutine s +end program p diff --git a/gcc/testsuite/gfortran.dg/optional_absent_6.f90 b/gcc/testsuite/gfortran.dg/optional_absent_6.f90 new file mode 100644 index 00000000000..b8abb06980a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/optional_absent_6.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +! PR fortran/107441 +! +! Test VALUE + OPTIONAL for integer/real/... +! in the presence of non-optional character dummies + +program bugdemo + implicit none + character :: s = 'a' + integer :: t + + t = testoptional(s) + call test2 (s) + call test3 (s) + call test4 (w='123',x=42) + +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 + if (present (x)) stop 1 + end function testoptional + + subroutine test2 (w, x) + character, intent(in) :: w + integer, intent(in), value, optional :: x + print*, 'present(x) is', present(x) + if (present (x)) stop 2 + end subroutine test2 + + subroutine test3 (w, x) + character, intent(in), optional :: w + integer, intent(in), value, optional :: x + print *, 'present(w) is', present(w) + print *, 'present(x) is', present(x) + if (.not. present (w)) stop 3 + if (present (x)) stop 4 + end subroutine test3 + + subroutine test4 (r, w, x) + real, value, optional :: r + character(*), intent(in), optional :: w + integer, value, optional :: x + print *, 'present(r) is', present(r) + print *, 'present(w) is', present(w) + print *, 'present(x) is', present(x) + if (present (r)) stop 5 + if (.not. present (w)) stop 6 + if (.not. present (x)) stop 7 + print *, 'x=', x + print *, 'len(w)=', len(w) + if (len(w) /= 3) stop 8 + if (x /= 42) stop 9 + end subroutine test4 + +end program bugdemo diff --git a/gcc/testsuite/gfortran.dg/optional_absent_7.f90 b/gcc/testsuite/gfortran.dg/optional_absent_7.f90 new file mode 100644 index 00000000000..efa7166c7e3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/optional_absent_7.f90 @@ -0,0 +1,30 @@ +! { dg-do run } +! { dg-additional-options "-fdump-tree-original" } +! +! PR fortran/107441 +! Check that procedure types and procedure decls match when the procedure +! has both character-typed and optional value args. +! +! Contributed by M.Morin + +program p + interface + subroutine i(c, o) + character(*) :: c + integer, optional, value :: o + end subroutine i + end interface + procedure(i), pointer :: pp + pp => s + call pp("abcd") +contains + subroutine s(c, o) + character(*) :: c + integer, optional, value :: o + if (present(o)) stop 1 + if (len(c) /= 4) stop 2 + if (c /= "abcd") stop 3 + end subroutine s +end program p + +! { dg-final { scan-tree-dump "void s .* c, .* o, logical.* _o, integer.* _c" "original" } } -- 2.35.3