diff mbox

Fix a function decl in gfortran

Message ID 538EB918.8050503@net-b.de
State New
Headers show

Commit Message

Tobias Burnus June 4, 2014, 6:13 a.m. UTC
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.

Comments

Tobias Burnus June 4, 2014, 7:40 a.m. UTC | #1
Still untested patch, but I cannot resist pointing out stupid
typos by myself.

I intent to tests the build and test the patch - and then to
commit it as obvious. If you see problems with this approach
please scream now.


On Wed, Jun 04, 2014 at 08:13:44AM +0200, Tobias Burnus wrote:
> +   To be used together with gfc_se->gnore_optional.  */

s/gnore/ignore/

> +   if (actual)
> +	{
> +	  gcc_assert (act_arg != NULL);
> +	  if (act_arg == NULL)

s/act_arg == NULL/act_arg->expr == NULL/


Tobias
Bernd Schmidt June 4, 2014, 11:55 a.m. UTC | #2
On 06/04/2014 09:40 AM, Tobias Burnus wrote:
> Still untested patch, but I cannot resist pointing out stupid
> typos by myself.
>
> I intent to tests the build and test the patch - and then to
> commit it as obvious. If you see problems with this approach
> please scream now.

I have no idea about the approach, but I'll be testing it on our nvptx 
compiler (results probably late today or tomorrow). Thanks!


Bernd
Bernd Schmidt June 4, 2014, 5:29 p.m. UTC | #3
On 06/04/2014 09:40 AM, Tobias Burnus wrote:
> Still untested patch, but I cannot resist pointing out stupid
> typos by myself.
>
> I intent to tests the build and test the patch - and then to
> commit it as obvious. If you see problems with this approach
> please scream now.

Even with this applied, I'm still seeing similar failures. I'm now 
looking at gfortran.dg/realloc_on_assign_1.f03 and related testcases.

(gdb) p gfc_debug_expr(gfc_expr*) (expr)
_gfortran_reshape_4[[((MAIN__:src(FULL)) ((/  ,  /)) ((arg not-present)) 
((arg not-present)))]]

[later:]

(gdb) p exp
$17 = <call_expr 0x7ffff064ac60>
(gdb) pge
_gfortran_reshape_4 (_631, _630, _629, 0B, 0B)

(gdb) p fndecl
$18 = <function_decl 0x7ffff07e5b00 _gfortran_reshape_4>
(gdb) pt
  <function_decl 0x7ffff07e5b00 _gfortran_reshape_4
     type <function_type
         type <void_type void VOID
             align 8 symtab 0 alias set -1 canonical type
             pointer_to_this <pointer_type>>
         SI
         size <integer_cst constant 32>
         unit size <integer_cst constant 4>
         align 32 symtab 0 alias set -1 canonical type
         attributes <tree_list
             purpose <identifier_node fn spec>
             value <tree_list 0x7ffff07fddc0
                 value <string_cst 0x7ffff07f8f60 constant ".wrr">>>
         arg-types <tree_list value <reference_type >
             chain <tree_list value <reference_type >
                 chain <tree_list value <reference_type >
                     chain <tree_list value <void_type void>>>>>
         pointer_to_this <pointer_type >>

and in libgfortran:

void
reshape_4 (gfc_array_i4 * const restrict ret,
         gfc_array_i4 * const restrict source,
         shape_type * const restrict shape,
         gfc_array_i4 * const restrict pad,
         shape_type * const restrict order)

So we're seeing more arguments in the call than on the decl (oddly the 
call only has four arguments at the assembly level, but that might a 
problem with my backend - I'll investigate).


Bernd
diff mbox

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);