public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "anlauf at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug fortran/92887] [F2008] Passing nullified/disassociated pointer or unalloc allocatable to  OPTIONAL + VALUE dummy fails
Date: Mon, 19 Jun 2023 18:51:37 +0000	[thread overview]
Message-ID: <bug-92887-4-H9ws6rCtnt@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-92887-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92887

--- Comment #6 from anlauf at gcc dot gnu.org ---
(In reply to Mikael Morin from comment #5)
> (In reply to anlauf from comment #4)
> > 
> > I'll need broader feedback, so unless someone adds to this pr, I'll submit
> > the present patch - with testcases - to get attention.
> > 
> Here you go:
> 
> > diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
> > index 45a984b6bdb..d9dcc11e5bd 100644
> > --- a/gcc/fortran/trans-expr.cc
> > +++ b/gcc/fortran/trans-expr.cc
> 
> > @@ -6396,7 +6399,28 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
> >  			&& fsym->ts.type != BT_CLASS
> >  			&& fsym->ts.type != BT_DERIVED)
> >  		      {
> > -			if (e->expr_type != EXPR_VARIABLE
> > +			/* F2018:15.5.2.12 Argument presence and
> > +			   restrictions on arguments not present.  */
> > +			if (e->expr_type == EXPR_VARIABLE
> > +			    && (e->symtree->n.sym->attr.allocatable
> > +				|| e->symtree->n.sym->attr.pointer))
> 
> Beware of expressions like derived%alloc_comp or derived%pointer_comp which
> don't match the above.

Right.  This is fixable by using


                            && (gfc_expr_attr (e).allocatable
                                || gfc_expr_attr (e).pointer))

instead.

> > @@ -7072,6 +7096,42 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
> >  	    }
> >  	}
> >  
> > +      /* F2023:15.5.3, 15.5.4: Actual argument expressions are evaluated
> > +	 before they are associated and a procedure is executed.  */
> > +      if (e && e->expr_type != EXPR_VARIABLE && !gfc_is_constant_expr (e))
> > +	{
> > +	  /* Create temporary except for functions returning pointers that
> > +	     can appear in a variable definition context.  */
> 
> Maybe explain *why* we have to create a temporary, that is some data
> references may become  undefined by the procedure call (intent(out) dummies)
> so we have to evaluate values depending on them beforehand (PR 92178).

That is one reason.  Another one, also pointed out in PR92178 by Tobias' review
of Steve's draft, is the first testcase at

https://gcc.gnu.org/legacy-ml/gcc-patches/2019-10/msg01970.html

This is reminiscent to an issue reported for the MERGE intrinsic (pr107874,
fixed so far, but there is a remaining issue in pr105371).

> > +	  if (e->expr_type != EXPR_FUNCTION
> > +	      || !(gfc_expr_attr (e).pointer || gfc_expr_attr (e).proc_pointer))
> 
> Merge with the outer condition?

Yes.  The above form was intended more for proof-of-concept and readability
than for coding standards.

> > +	    need_temp = true;
> > +	}
> > +
> > +      if (need_temp)
> > +	{
> > +	  if (cond_temp == NULL_TREE)
> > +	    parmse.expr = gfc_evaluate_now (parmse.expr, &parmse.pre);
> 
> I'm not sure about this.  The condition to set need_temp looks quite general
> (especially it matches non-scalar cases, doesn't it?), but
> gfc_conv_expr_reference should already take care of creating a variable, so
> that a temporary is missing only for value dummies, I think.  I would rather
> move this to the place specific to value dummies.

I agree in principle.  The indentation level is already awful in the specific
place, which calls for thoughts about refactoring that mega-loop over the
arguments than currently spans far more than 1000 source code lines.

> I think this PR is only about scalars with basic types, is there the same
> problem with derived types?  with classes?
> I guess arrays are different as they are always by reference?

For the current documentation of the argument passing convention see:

https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html

"For OPTIONAL dummy arguments, an absent argument is denoted by a NULL pointer,
except for scalar dummy arguments of intrinsic type which have the VALUE
attribute. For those, a hidden Boolean argument (logical(kind=C_bool),value) is
used to indicate whether the argument is present."

My understanding is that for these scalar arguments we do need something that
can be passed by value.

We currently do not support VALUE with array arguments (F2008+), character
of length > 1, and character actual arguments are broken unless they are
constants.  There are several open PRs.

> > +	  else
> 
> I would rather move the else part to the place above where cond_temp is set,
> so that the code is easier to follow.
> 
> > +	    {
> > +	      /* "Conditional temporary" to handle variables that possibly
> > +		 cannot be dereferenced.  Use null value as fallback.  */
> > +	      tree dflt_temp;
> > +	      gcc_assert (e->ts.type != BT_DERIVED && e->ts.type != BT_CLASS);
> > +	      gcc_assert (e->rank == 0);
> > +	      dflt_temp = gfc_create_var (TREE_TYPE (parmse.expr), "temp");
> > +	      TREE_STATIC (dflt_temp) = 1;
> > +	      TREE_CONSTANT (dflt_temp) = 1;
> > +	      TREE_READONLY (dflt_temp) = 1;
> > +	      DECL_INITIAL (dflt_temp) = build_zero_cst (TREE_TYPE (dflt_temp));
> > +	      parmse.expr = fold_build3_loc (input_location, COND_EXPR,
> > +					     TREE_TYPE (parmse.expr),
> > +					     cond_temp,
> > +					     parmse.expr, dflt_temp);
> > +	      parmse.expr = gfc_evaluate_now (parmse.expr, &parmse.pre);
> > +	    }
> > +	}
> > +
> > +
> >        if (fsym && need_interface_mapping && e)
> >  	gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
> >

I agree that it was a bad idea to merge the patches for these two PRs just
because temporaries are needed.

  parent reply	other threads:[~2023-06-19 18:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <bug-92887-4@http.gcc.gnu.org/bugzilla/>
2023-06-16 19:44 ` anlauf at gcc dot gnu.org
2023-06-17 19:52 ` anlauf at gcc dot gnu.org
2023-06-17 20:11 ` anlauf at gcc dot gnu.org
2023-06-18 20:03 ` anlauf at gcc dot gnu.org
2023-06-19  9:09 ` mikael at gcc dot gnu.org
2023-06-19 18:51 ` anlauf at gcc dot gnu.org [this message]
2023-06-20  8:11 ` mikael at gcc dot gnu.org
2023-11-01 22:11 ` anlauf at gcc dot gnu.org
2023-11-03 17:49 ` cvs-commit at gcc dot gnu.org
2023-11-03 20:15 ` anlauf at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-92887-4-H9ws6rCtnt@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).