Tobias Burnus wrote:
There are two functions groups called with mask, cf. iresolve.c's
gfc_resolve_minloc. Namely, without dim "mmin0_<kind>_<type>" and with
dim "mmin1_<kind>_<type>". – The latter takes "dim" as additional
argument.
Thus, for mmin1_* the generated decl is fine, for mmin0_ is is not. I
do not immediately see where the "dim" argument is skipped – but some
similar special-case handling would then be also needed for the
function declaration.
To answer myself: gfc_conv_intrinsic_function sets "se->ignore_optional"
– and, thus, dim= is not passed as actual argument.
I think what's needed is to modify gfc_copy_formal_args_intr – called by
trans-intrinsic.c's gfc_get_symbol_for_expr – such that it optionally
ignores absent optionals, i.e. passing expr->value.function.actual and
walking it along the formal arguments, skipping the formal argument when
actual->expr == NULL.
Tobias
PS: I have attached a completely untested draft patch.
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3e5cdbd..1df79fd 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2750,3 +2787,4 @@ bool gfc_type_compatible (gfc_typespec *, gfc_typespec *);
-void gfc_copy_formal_args_intr (gfc_symbol *, gfc_intrinsic_sym *);
+void gfc_copy_formal_args_intr (gfc_symbol *, gfc_intrinsic_sym *,
+ gfc_actual_arglist *);
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 7579573..d224d6e 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1676,3 +1676,3 @@ gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc)
- gfc_copy_formal_args_intr (sym, isym);
+ gfc_copy_formal_args_intr (sym, isym, NULL);
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 3785c2e..bb5b440 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4017,6 +4044,10 @@ add_proc_interface (gfc_symbol *sym, ifsrc source, gfc_formal_arglist *formal)
declaration statement (see match_proc_decl()) to create the formal
- args based on the args of a given named interface. */
+ args based on the args of a given named interface.
+
+ When an actual argument list is provided, skip the absent arguments.
+ To be used together with gfc_se->gnore_optional. */
void
-gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src)
+gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src,
+ gfc_actual_arglist *actual)
{
@@ -4027,2 +4058,3 @@ gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src)
gfc_formal_arglist *formal_prev = NULL;
+ gfc_actual_arglist *act_arg = actual;
/* Save current namespace so we can change it for formal args. */
@@ -4037,2 +4069,13 @@ gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src)
{
+ /* Skip absent arguments. */
+ if (actual)
+ {
+ gcc_assert (act_arg != NULL);
+ if (act_arg == NULL)
+ {
+ act_arg = act_arg->next;
+ continue;
+ }
+ act_arg = act_arg->next;
+ }
formal_arg = gfc_get_formal_arglist ();
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index a76d0f7..f89b45c 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -2396,3 +2769,4 @@ gfc_get_symbol_for_expr (gfc_expr * expr)
- gfc_copy_formal_args_intr (sym, expr->value.function.isym);
+ gfc_copy_formal_args_intr (sym, expr->value.function.isym,
+ expr->value.function.actual);