diff options
author | Harald Anlauf <anlauf@gmx.de> | 2022-10-28 21:58:08 +0200 |
---|---|---|
committer | Harald Anlauf <anlauf@gmx.de> | 2022-11-09 20:51:56 +0100 |
commit | e805adaa283129604a1fb305d0a1cf1e8a90c76e (patch) | |
tree | 55607d4e9c73577f962629a15d020a504460963e /gcc/fortran/trans-decl.cc | |
parent | 8f5aa130fa61637baec476119e72849f7e3f8c67 (diff) | |
download | gcc-e805adaa283129604a1fb305d0a1cf1e8a90c76e.zip gcc-e805adaa283129604a1fb305d0a1cf1e8a90c76e.tar.gz gcc-e805adaa283129604a1fb305d0a1cf1e8a90c76e.tar.bz2 |
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.
Diffstat (limited to 'gcc/fortran/trans-decl.cc')
-rw-r--r-- | gcc/fortran/trans-decl.cc | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 63515b9..94988b8 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -2507,8 +2507,8 @@ create_function_arglist (gfc_symbol * sym) { tree fndecl; gfc_formal_arglist *f; - tree typelist, hidden_typelist; - tree arglist, hidden_arglist; + tree typelist, hidden_typelist, optval_typelist; + 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) @@ -2619,6 +2620,15 @@ create_function_arglist (gfc_symbol * sym) if (f->sym != NULL) /* Ignore alternate returns. */ hidden_typelist = TREE_CHAIN (hidden_typelist); + /* Advance hidden_typelist over optional+value argument presence flags. */ + optval_typelist = hidden_typelist; + for (f = gfc_sym_get_dummy_args (sym); f; f = f->next) + if (f->sym != NULL + && f->sym->attr.optional && f->sym->attr.value + && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS + && !gfc_bt_struct (f->sym->ts.type)) + hidden_typelist = TREE_CHAIN (hidden_typelist); + for (f = gfc_sym_get_dummy_args (sym); f; f = f->next) { char name[GFC_MAX_SYMBOL_LEN + 2]; @@ -2712,14 +2722,16 @@ 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; TREE_READONLY (tmp) = 1; gfc_finish_decl (tmp); - hidden_typelist = TREE_CHAIN (hidden_typelist); + /* The presence flag must be boolean. */ + gcc_assert (TREE_VALUE (optval_typelist) == boolean_type_node); + optval_typelist = TREE_CHAIN (optval_typelist); } /* For non-constant length array arguments, make sure they use @@ -2863,6 +2875,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) |