diff options
author | Harald Anlauf <anlauf@gmx.de> | 2022-11-10 22:30:27 +0100 |
---|---|---|
committer | Harald Anlauf <anlauf@gmx.de> | 2022-11-12 21:03:28 +0100 |
commit | 59a63247992eb13153b82c4902aadf111460eac2 (patch) | |
tree | be43ce02582ae5ddd62d4d5f542891da8288e8d5 /gcc/fortran/trans-expr.cc | |
parent | b556d1773db7174c71c466d9b3cafc25c7d6c825 (diff) | |
download | gcc-59a63247992eb13153b82c4902aadf111460eac2.zip gcc-59a63247992eb13153b82c4902aadf111460eac2.tar.gz gcc-59a63247992eb13153b82c4902aadf111460eac2.tar.bz2 |
Fortran: fix treatment of character, value, optional dummy arguments [PR107444]
Fix handling of character dummy arguments that have the optional+value
attribute. Change name of internal symbols that carry the hidden presence
status of optional arguments to distinguish them from the internal hidden
character length. Update documentation to clarify the gfortran ABI.
gcc/fortran/ChangeLog:
PR fortran/107444
* trans-decl.cc (create_function_arglist): Extend presence status
to all intrinsic types, and change prefix of internal symbol to '.'.
* trans-expr.cc (gfc_conv_expr_present): Align to changes in
create_function_arglist.
(gfc_conv_procedure_call): Fix generation of procedure arguments for
the case of character dummy arguments with optional+value attribute.
* trans-types.cc (gfc_get_function_type): Synchronize with changes
to create_function_arglist.
* doc/gfortran/naming-and-argument-passing-conventions.rst: Clarify
the gfortran argument passing conventions with regard to OPTIONAL
dummy arguments of intrinsic type.
gcc/testsuite/ChangeLog:
PR fortran/107444
* gfortran.dg/optional_absent_7.f90: Adjust regex.
* gfortran.dg/optional_absent_8.f90: New test.
Diffstat (limited to 'gcc/fortran/trans-expr.cc')
-rw-r--r-- | gcc/fortran/trans-expr.cc | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index f3fbb52..b95c5cf 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1985,15 +1985,14 @@ gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc) /* Intrinsic scalars with VALUE attribute which are passed by value use a hidden argument to denote the present status. */ - if (sym->attr.value && sym->ts.type != BT_CHARACTER - && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED - && !sym->attr.dimension) + if (sym->attr.value && !sym->attr.dimension + && sym->ts.type != BT_CLASS && !gfc_bt_struct (sym->ts.type)) { char name[GFC_MAX_SYMBOL_LEN + 2]; tree tree_name; gcc_assert (TREE_CODE (decl) == PARM_DECL); - name[0] = '_'; + name[0] = '.'; strcpy (&name[1], sym->name); tree_name = get_identifier (name); @@ -6162,11 +6161,21 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, value, pass "0" and a hidden argument gives the optional status. */ if (fsym && fsym->attr.optional && fsym->attr.value - && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER - && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED) + && !fsym->attr.dimension && fsym->ts.type != BT_CLASS + && !gfc_bt_struct (sym->ts.type)) { - parmse.expr = fold_convert (gfc_sym_type (fsym), - integer_zero_node); + if (fsym->ts.type == BT_CHARACTER) + { + /* Pass a NULL pointer for an absent CHARACTER arg + and a length of zero. */ + parmse.expr = null_pointer_node; + parmse.string_length + = build_int_cst (gfc_charlen_type_node, + 0); + } + else + parmse.expr = fold_convert (gfc_sym_type (fsym), + integer_zero_node); vec_safe_push (optionalargs, boolean_false_node); } else |