Hi!

The following patch fixes
-FAIL: libgomp.fortran/use_device_addr-1.f90   -O0  execution test
-FAIL: libgomp.fortran/use_device_addr-2.f90   -O0  execution test
that has been FAILing for several months on powerpc64le-linux.
The problem is in the Fortran FE, which adds the artificial arguments
for scalar VALUE OPTIONAL dummy args only to DECL_ARGUMENTS where the
current function can see them, but not to TYPE_ARG_TYPES; if those functions
aren't varargs, this confuses calls.c to pass the remaining arguments
(which aren't named (== not covered by TYPE_ARG_TYPES) and aren't varargs
either) in a different spot from what the callee (which has proper
DECL_ARGUMENTS for all args) expects.  For the artificial length arguments
for character dummy args we already put them in both DECL_ARGUMENTS and
TYPE_ARG_TYPES.

Fixed thusly, bootstrapped/regtested on x86_64-linux, i686-linux,
powerpc64le-linux and powerpc64-linux (the last one with both -m32/-m64).
Ok for trunk?

2020-01-31  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/92305
        * trans-types.c (gfc_get_function_type): Also push boolean_type_node
        types for non-character scalar VALUE optional dummy arguments.
        * trans-decl.c (create_function_arglist): Skip those in
        hidden_typelist.  Formatting fix.

--- gcc/fortran/trans-types.c.jj        2020-01-12 11:54:36.000000000 +0100
+++ gcc/fortran/trans-types.c   2020-01-31 21:26:34.199188677 +0100
@@ -3098,6 +3098,16 @@ gfc_get_function_type (gfc_symbol * sym,
 
          vec_safe_push (typelist, type);
        }
+      /* For noncharacter scalar intrinsic types, VALUE passes the value,
+        hence, the optional status cannot be transferred via a NULL pointer.
+        Thus, we will use a hidden argument in that case.  */
+      else if (arg
+              && arg->attr.optional
+              && arg->attr.value
+              && !arg->attr.dimension
+              && arg->ts.type != BT_CLASS
+              && !gfc_bt_struct (arg->ts.type))
+       vec_safe_push (typelist, boolean_type_node);
     }
 
   if (!vec_safe_is_empty (typelist)
--- gcc/fortran/trans-decl.c.jj 2020-01-30 09:34:43.207088430 +0100
+++ gcc/fortran/trans-decl.c    2020-01-31 21:28:49.272197084 +0100
@@ -2645,8 +2645,8 @@ create_function_arglist (gfc_symbol * sy
              || f->sym->ts.u.cl->backend_decl == length)
            {
              if (POINTER_TYPE_P (len_type))
-               f->sym->ts.u.cl->backend_decl =
-                       build_fold_indirect_ref_loc (input_location, length);
+               f->sym->ts.u.cl->backend_decl
+                 = build_fold_indirect_ref_loc (input_location, length);
              else if (f->sym->ts.u.cl->backend_decl == NULL)
                gfc_create_string_length (f->sym);
 
@@ -2677,6 +2677,8 @@ create_function_arglist (gfc_symbol * sy
           DECL_ARG_TYPE (tmp) = boolean_type_node;
           TREE_READONLY (tmp) = 1;
           gfc_finish_decl (tmp);
+
+         hidden_typelist = TREE_CHAIN (hidden_typelist);
        }
 
       /* For non-constant length array arguments, make sure they use

        Jakub

Reply via email to