aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.cc
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2022-10-28 21:58:08 +0200
committerHarald Anlauf <anlauf@gmx.de>2022-11-09 20:51:56 +0100
commite805adaa283129604a1fb305d0a1cf1e8a90c76e (patch)
tree55607d4e9c73577f962629a15d020a504460963e /gcc/fortran/trans-decl.cc
parent8f5aa130fa61637baec476119e72849f7e3f8c67 (diff)
downloadgcc-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.cc23
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)