Both ifort and g95 produce viable executables with the following:

  logical :: back =.true.
  print *, myscan ("The quick brown fox jumped over the lazy dog", &
                    "brown", back)
  print *, myscan ("The quick brown fox jumped over the lazy dog", &
                    "lazy")
contains
  integer function myscan (str, substr, back)
    character(*), intent(in) :: str, substr
    logical, optional, intent(in) :: back
    myscan = scan (str, substr, back)
  end function myscan
end

gfortran seg faults in executing the second call myscan because the call to
intrinsic scan is made with in indirect reference to NULL; ie. the missing
argument back.

I think that, strictly speaking, the outcome of this code is not defined by the
standard.  However, it does seem that other compilers quietly do the right
thing.

This fixes it:

Index: gcc/fortran/trans-intrinsic.c

===================================================================

--- gcc/fortran/trans-intrinsic.c       (révision 112278)

+++ gcc/fortran/trans-intrinsic.c       (copie de travail)

@@ -159,14 +159,42 @@

 real_compnt_info;


+/* Converts a missing, optional argument into a null or zero, if the
+   formal argument is optional.  */
+
+static void
+gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_expr * expr)
+{
+  gfc_actual_arglist *actual;
+  gfc_intrinsic_arg  *formal;
+  tree tmp;
+
+  formal = expr->value.function.isym->formal;
+  if (formal == NULL)
+    return;
+
+  for (actual = expr->value.function.actual; actual; actual = actual->next,
+       formal = formal ? formal->next : NULL)
+    if (actual->expr == arg && formal && formal->optional)
+      {
+       tmp = gfc_conv_expr_present (actual->expr->symtree->n.sym);
+       tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), tmp, se->expr,
+                     convert (TREE_TYPE (se->expr), integer_zero_node));
+       tmp = gfc_evaluate_now (tmp, &se->pre);
+       se->expr = tmp;
+       return;
+      }
+}
+
+
 /* Evaluate the arguments to an intrinsic function.  */

 static tree
 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
 {
   gfc_actual_arglist *actual;
+  gfc_se argse;
   tree args;
-  gfc_se argse;

   args = NULL_TREE;
   for (actual = expr->value.function.actual; actual; actual = actual->next)
@@ -188,6 +216,10 @@

       else
         gfc_conv_expr_val (&argse, actual->expr);

+      if (actual->expr->expr_type ==EXPR_VARIABLE
+           && actual->expr->symtree->n.sym->attr.optional)
+       gfc_conv_missing_dummy (&argse, actual->expr, expr);
+
       gfc_add_block_to_block (&se->pre, &argse.pre);
       gfc_add_block_to_block (&se->post, &argse.post);
       args = gfc_chainon_list (args, argse.expr);

I will persue the standard before submitting this patch - I need to decide if
the conversion should be conditional on the standard in force and if
gfc_conv_function_call needs to be treated in the same way.

Paul


-- 
           Summary: Automatic conversion for optional parameters of missing
                    dummies
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: pault at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26891

Reply via email to