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
> logical, optional, intent(in) :: back > myscan = scan (str, substr, back) I thought passing non-present optional arguments down to routines as an optional argument is within the confines of the Standard. If in doubt, consult comp.lang.fortran ...
Subject: Re: Automatic conversion for optional parameters of missing dummies toon at moene dot indiv dot nluug dot nl wrote: >------- Comment #1 from toon at moene dot indiv dot nluug dot nl 2006-03-28 08:15 ------- > > >> logical, optional, intent(in) :: back >> myscan = scan (str, substr, back) >> >> > >I thought passing non-present optional arguments down to routines as an >optional argument is within the confines of the Standard. > >If in doubt, consult comp.lang.fortran ... > > I would rather curl up in front of the fire with the standard - comp.lang.fortran comes with a population that seems excessively "up yours" on such matters. I cannot be bothered with the aggression. However, if you are right, that's great; I will spread the solution to all procedure calls. Right now, I need to get out of this TRANSFER mess! Best regards Paul
According to the standard: 12.4.1.5 Restriction on dummy arguments not present. ..... Except as noted in the list above, it may be supplied as an actual argument corresponding to an optional dummy argument, which is also considered not to be associated with an actual argument. I will generalise the above and submit the patch tonight.
Subject: Bug number PR26891 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01828.html
*** Bug 27035 has been marked as a duplicate of this bug. ***
Subject: Bug 26891 Author: hjl Date: Wed Apr 5 13:23:35 2006 New Revision: 112701 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112701 Log: Correct PR number in ChangeLogs. gcc/fortran/ 2006-04-03 Paul Thomas <pault@gcc.gnu.org> PR fortran/26891 * trans.h : Prototype for gfc_conv_missing_dummy. * trans-expr (gfc_conv_missing_dummy): New function (gfc_conv_function_call): Call it and tidy up some of the code. * trans-intrinsic (gfc_conv_intrinsic_function_args): The same. gcc/testsuite/ 2006-04-03 Paul Thomas <pault@gcc.gnu.org> PR fortran/26891 * gfortran.dg/missing_optional_dummy_1.f90: New test. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/testsuite/ChangeLog
Subject: Bug 26891 Author: pault Date: Fri Apr 7 06:02:05 2006 New Revision: 112748 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112748 Log: 2006-04-07 Paul Thomas <pault@gcc.gnu.org> PR fortran/26891 * trans.h : Prototype for gfc_conv_missing_dummy. * trans-expr (gfc_conv_missing_dummy): New function (gfc_conv_function_call): Call it and tidy up some of the code. * trans-intrinsic (gfc_conv_intrinsic_function_args): The same. PR fortran/26976 * array.c (gfc_array_dimen_size): If available, return shape[dimen] * resolve.c (resolve_function): If available, use the argument shape for the function expression. * iresolve.c (gfc_resolve_transfer): Set shape[0] = size. PR fortran/26779 *resolve.c (resolve_fl_procedure): Do not check the access of derived types for internal procedures. 2006-04-07 Paul Thomas <pault@gcc.gnu.org> PR fortran/26891 * gfortran.dg/missing_optional_dummy_1.f90: New test. PR fortran/26976 * gfortran.dg/compliant_elemental_intrinsics_1.f90: New test. * gfortran.dg/initialization_1.f90: Make assignment compliant. * gfortran.dg/transfer_array_intrinsic_1.f90: Simplify. * gfortran.dg/transfer_array_intrinsic_2.f90: Make assignments compliant and detect bigendian-ness. PR fortran/26779 * gfortran.dg/private_type_5.f90: New test. Added: branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/compliant_elemental_intrinsics_1.f90 branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/missing_optional_dummy_1.f90 (with props) branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/private_type_5.f90 Modified: branches/gcc-4_1-branch/gcc/fortran/ChangeLog branches/gcc-4_1-branch/gcc/fortran/array.c branches/gcc-4_1-branch/gcc/fortran/iresolve.c branches/gcc-4_1-branch/gcc/fortran/resolve.c branches/gcc-4_1-branch/gcc/fortran/trans-expr.c branches/gcc-4_1-branch/gcc/fortran/trans-intrinsic.c branches/gcc-4_1-branch/gcc/fortran/trans.h branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/initialization_1.f90 branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/transfer_array_intrinsic_1.f90 branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/transfer_array_intrinsic_2.f90 Propchange: branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/missing_optional_dummy_1.f90 ('svn:executable' added)
Fixed trunk and 4.1 Paul