Re: [Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-08 Thread Paul Richard Thomas via Gcc-patches
Thanks Gents!

The solution is to gfc_free_expr (p) if the replacement is not made.

I am regtesting a patch for PR107900. I'll include the fix for the
memory leak in the patch for that.

Cheers

Paul


On Thu, 8 Jun 2023 at 09:30, Harald Anlauf  wrote:
>
> On 6/8/23 09:46, Mikael Morin wrote:
> > Le 08/06/2023 à 07:57, Paul Richard Thomas via Fortran a écrit :
> >> Hi Harald,
> >>
> >> In answer to your question:
> >> void
> >> gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
> >> {
> >>free_expr0 (dest);
> >>*dest = *src;
> >>free (src);
> >> }
> >> So it does indeed do the job.
> >>
> > Sure, but his comment was about the case gfc_replace_expr is *not*
> > executed.
>
> Right.  The following legal code exhibits the leak, pointing
> to the gfc_copy_expr:
>
> subroutine paul (n)
>integer  :: n
>character(n) :: c
> end
>
> >> I should perhaps have remarked that, following the divide error,
> >> gfc_simplify_expr was returning a mutilated version of the expression
> >> and this was somehow connected with successfully simplifying the
> >> parentheses. Copying and replacing on no errors deals with the
> >> problem.
> >>
> > Is the expression mutilated enough that it can't be safely freed?
> >
> >
> >
>


-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Re: [Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-08 Thread Harald Anlauf via Gcc-patches

On 6/8/23 09:46, Mikael Morin wrote:

Le 08/06/2023 à 07:57, Paul Richard Thomas via Fortran a écrit :

Hi Harald,

In answer to your question:
void
gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
{
   free_expr0 (dest);
   *dest = *src;
   free (src);
}
So it does indeed do the job.

Sure, but his comment was about the case gfc_replace_expr is *not* 
executed.


Right.  The following legal code exhibits the leak, pointing
to the gfc_copy_expr:

subroutine paul (n)
  integer  :: n
  character(n) :: c
end


I should perhaps have remarked that, following the divide error,
gfc_simplify_expr was returning a mutilated version of the expression
and this was somehow connected with successfully simplifying the
parentheses. Copying and replacing on no errors deals with the
problem.


Is the expression mutilated enough that it can't be safely freed?








Re: [Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-08 Thread Mikael Morin

Le 08/06/2023 à 07:57, Paul Richard Thomas via Fortran a écrit :

Hi Harald,

In answer to your question:
void
gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
{
   free_expr0 (dest);
   *dest = *src;
   free (src);
}
So it does indeed do the job.


Sure, but his comment was about the case gfc_replace_expr is *not* executed.


I should perhaps have remarked that, following the divide error,
gfc_simplify_expr was returning a mutilated version of the expression
and this was somehow connected with successfully simplifying the
parentheses. Copying and replacing on no errors deals with the
problem.


Is the expression mutilated enough that it can't be safely freed?




Re: [Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-07 Thread Paul Richard Thomas via Gcc-patches
Hi Harald,

In answer to your question:
void
gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
{
  free_expr0 (dest);
  *dest = *src;
  free (src);
}
So it does indeed do the job.

I should perhaps have remarked that, following the divide error,
gfc_simplify_expr was returning a mutilated version of the expression
and this was somehow connected with successfully simplifying the
parentheses. Copying and replacing on no errors deals with the
problem.

Thanks

Paul

On Wed, 7 Jun 2023 at 19:38, Harald Anlauf  wrote:
>
> Hi Paul!
>
> On 6/7/23 18:10, Paul Richard Thomas via Gcc-patches wrote:
> > Hi All,
> >
> > Three more fixes for PR87477. Please note that PR99350 was a blocker
> > but, as pointed out in comment #5 of the PR, this has nothing to do
> > with the associate construct.
> >
> > All three fixes are straight forward and the .diff + ChangeLog suffice
> > to explain them. 'rankguessed' was made redundant by the last PR87477
> > fix.
> >
> > Regtests on x86_64 - good for mainline?
> >
> > Paul
> >
> > Fortran: Fix some more blockers in associate meta-bug [PR87477]
> >
> > 2023-06-07  Paul Thomas  
> >
> > gcc/fortran
> > PR fortran/99350
> > * decl.cc (char_len_param_value): Simplify a copy of the expr
> > and replace the original if there is no error.
>
> This seems to lack a gfc_free_expr (p) in case the gfc_replace_expr
> is not executed, leading to a possible memleak.  Can you check?
>
> @@ -1081,10 +1082,10 @@ char_len_param_value (gfc_expr **expr, bool
> *deferred)
> if (!gfc_expr_check_typed (*expr, gfc_current_ns, false))
>   return MATCH_ERROR;
>
> -  /* If gfortran gets an EXPR_OP, try to simplify it.  This catches things
> - like CHARACTER(([1])).   */
> -  if ((*expr)->expr_type == EXPR_OP)
> -gfc_simplify_expr (*expr, 1);
> +  /* Try to simplify the expression to catch things like
> CHARACTER(([1])).   */
> +  p = gfc_copy_expr (*expr);
> +  if (gfc_is_constant_expr (p) && gfc_simplify_expr (p, 1))
> +gfc_replace_expr (*expr, p);
> else
>   gfc_free_expr (p);
>
> > * gfortran.h : Remove the redundant field 'rankguessed' from
> > 'gfc_association_list'.
> > * resolve.cc (resolve_assoc_var): Remove refs to 'rankguessed'.
> >
> > PR fortran/107281
> > * resolve.cc (resolve_variable): Associate names with constant
> > or structure constructor targets cannot have array refs.
> >
> > PR fortran/109451
> > * trans-array.cc (gfc_conv_expr_descriptor): Guard expression
> > character length backend decl before using it. Suppress the
> > assignment if lhs equals rhs.
> > * trans-io.cc (gfc_trans_transfer): Scalarize transfer of
> > associate variables pointing to a variable. Add comment.
> > * trans-stmt.cc (trans_associate_var): Remove requirement that
> > the character length be deferred before assigning the value
> > returned by gfc_conv_expr_descriptor. Also, guard the backend
> > decl before testing with VAR_P.
> >
> > gcc/testsuite/
> > PR fortran/99350
> > * gfortran.dg/pr99350.f90 : New test.
> >
> > PR fortran/107281
> > * gfortran.dg/associate_5.f03 : Changed error message.
> > * gfortran.dg/pr107281.f90 : New test.
> >
> > PR fortran/109451
> > * gfortran.dg/associate_61.f90 : New test
>
> Otherwise LGTM.
>
> Thanks for the patch!
>
> Harald
>
>


-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Re: [Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-07 Thread Harald Anlauf via Gcc-patches

Hi Paul!

On 6/7/23 18:10, Paul Richard Thomas via Gcc-patches wrote:

Hi All,

Three more fixes for PR87477. Please note that PR99350 was a blocker
but, as pointed out in comment #5 of the PR, this has nothing to do
with the associate construct.

All three fixes are straight forward and the .diff + ChangeLog suffice
to explain them. 'rankguessed' was made redundant by the last PR87477
fix.

Regtests on x86_64 - good for mainline?

Paul

Fortran: Fix some more blockers in associate meta-bug [PR87477]

2023-06-07  Paul Thomas  

gcc/fortran
PR fortran/99350
* decl.cc (char_len_param_value): Simplify a copy of the expr
and replace the original if there is no error.


This seems to lack a gfc_free_expr (p) in case the gfc_replace_expr
is not executed, leading to a possible memleak.  Can you check?

@@ -1081,10 +1082,10 @@ char_len_param_value (gfc_expr **expr, bool
*deferred)
   if (!gfc_expr_check_typed (*expr, gfc_current_ns, false))
 return MATCH_ERROR;

-  /* If gfortran gets an EXPR_OP, try to simplify it.  This catches things
- like CHARACTER(([1])).   */
-  if ((*expr)->expr_type == EXPR_OP)
-gfc_simplify_expr (*expr, 1);
+  /* Try to simplify the expression to catch things like
CHARACTER(([1])).   */
+  p = gfc_copy_expr (*expr);
+  if (gfc_is_constant_expr (p) && gfc_simplify_expr (p, 1))
+gfc_replace_expr (*expr, p);
   else
 gfc_free_expr (p);


* gfortran.h : Remove the redundant field 'rankguessed' from
'gfc_association_list'.
* resolve.cc (resolve_assoc_var): Remove refs to 'rankguessed'.

PR fortran/107281
* resolve.cc (resolve_variable): Associate names with constant
or structure constructor targets cannot have array refs.

PR fortran/109451
* trans-array.cc (gfc_conv_expr_descriptor): Guard expression
character length backend decl before using it. Suppress the
assignment if lhs equals rhs.
* trans-io.cc (gfc_trans_transfer): Scalarize transfer of
associate variables pointing to a variable. Add comment.
* trans-stmt.cc (trans_associate_var): Remove requirement that
the character length be deferred before assigning the value
returned by gfc_conv_expr_descriptor. Also, guard the backend
decl before testing with VAR_P.

gcc/testsuite/
PR fortran/99350
* gfortran.dg/pr99350.f90 : New test.

PR fortran/107281
* gfortran.dg/associate_5.f03 : Changed error message.
* gfortran.dg/pr107281.f90 : New test.

PR fortran/109451
* gfortran.dg/associate_61.f90 : New test


Otherwise LGTM.

Thanks for the patch!

Harald




[Patch, fortran] PR87477 - (associate) - [meta-bug] [F03] issues concerning the ASSOCIATE statement

2023-06-07 Thread Paul Richard Thomas via Gcc-patches
Hi All,

Three more fixes for PR87477. Please note that PR99350 was a blocker
but, as pointed out in comment #5 of the PR, this has nothing to do
with the associate construct.

All three fixes are straight forward and the .diff + ChangeLog suffice
to explain them. 'rankguessed' was made redundant by the last PR87477
fix.

Regtests on x86_64 - good for mainline?

Paul

Fortran: Fix some more blockers in associate meta-bug [PR87477]

2023-06-07  Paul Thomas  

gcc/fortran
PR fortran/99350
* decl.cc (char_len_param_value): Simplify a copy of the expr
and replace the original if there is no error.
* gfortran.h : Remove the redundant field 'rankguessed' from
'gfc_association_list'.
* resolve.cc (resolve_assoc_var): Remove refs to 'rankguessed'.

PR fortran/107281
* resolve.cc (resolve_variable): Associate names with constant
or structure constructor targets cannot have array refs.

PR fortran/109451
* trans-array.cc (gfc_conv_expr_descriptor): Guard expression
character length backend decl before using it. Suppress the
assignment if lhs equals rhs.
* trans-io.cc (gfc_trans_transfer): Scalarize transfer of
associate variables pointing to a variable. Add comment.
* trans-stmt.cc (trans_associate_var): Remove requirement that
the character length be deferred before assigning the value
returned by gfc_conv_expr_descriptor. Also, guard the backend
decl before testing with VAR_P.

gcc/testsuite/
PR fortran/99350
* gfortran.dg/pr99350.f90 : New test.

PR fortran/107281
* gfortran.dg/associate_5.f03 : Changed error message.
* gfortran.dg/pr107281.f90 : New test.

PR fortran/109451
* gfortran.dg/associate_61.f90 : New test
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index f5d39e2a3d8..d09c8bc97d9 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -1056,6 +1056,7 @@ static match
 char_len_param_value (gfc_expr **expr, bool *deferred)
 {
   match m;
+  gfc_expr *p;
 
   *expr = NULL;
   *deferred = false;
@@ -1081,10 +1082,10 @@ char_len_param_value (gfc_expr **expr, bool *deferred)
   if (!gfc_expr_check_typed (*expr, gfc_current_ns, false))
 return MATCH_ERROR;
 
-  /* If gfortran gets an EXPR_OP, try to simplify it.  This catches things
- like CHARACTER(([1])).   */
-  if ((*expr)->expr_type == EXPR_OP)
-gfc_simplify_expr (*expr, 1);
+  /* Try to simplify the expression to catch things like CHARACTER(([1])).   */
+  p = gfc_copy_expr (*expr);
+  if (gfc_is_constant_expr (p) && gfc_simplify_expr (p, 1))
+gfc_replace_expr (*expr, p);
 
   if ((*expr)->expr_type == EXPR_FUNCTION)
 {
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3e5f942d7fd..a65dd571591 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2914,9 +2914,6 @@ typedef struct gfc_association_list
  for memory handling.  */
   unsigned dangling:1;
 
-  /* True when the rank of the target expression is guessed during parsing.  */
-  unsigned rankguessed:1;
-
   char name[GFC_MAX_SYMBOL_LEN + 1];
   gfc_symtree *st; /* Symtree corresponding to name.  */
   locus where;
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 2ba3101f1fe..f2604314570 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -5872,7 +5872,15 @@ resolve_variable (gfc_expr *e)
   if (sym->ts.type == BT_CLASS)
 	gfc_fix_class_refs (e);
   if (!sym->attr.dimension && e->ref && e->ref->type == REF_ARRAY)
-	return false;
+	{
+	  /* Unambiguously scalar!  */
+	  if (sym->assoc->target
+	  && (sym->assoc->target->expr_type == EXPR_CONSTANT
+		  || sym->assoc->target->expr_type == EXPR_STRUCTURE))
+	gfc_error ("Scalar variable %qs has an array reference at %L",
+		   sym->name, &e->where);
+	  return false;
+	}
   else if (sym->attr.dimension && (!e->ref || e->ref->type != REF_ARRAY))
 	{
 	  /* This can happen because the parser did not detect that the
@@ -9279,7 +9287,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
   gfc_array_spec *as;
   /* The rank may be incorrectly guessed at parsing, therefore make sure
 	 it is corrected now.  */
-  if (sym->ts.type != BT_CLASS && (!sym->as || sym->assoc->rankguessed))
+  if (sym->ts.type != BT_CLASS && !sym->as)
 	{
 	  if (!sym->as)
 	sym->as = gfc_get_array_spec ();
@@ -9292,8 +9300,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
 	sym->attr.codimension = 1;
 	}
   else if (sym->ts.type == BT_CLASS
-	   && CLASS_DATA (sym)
-	   && (!CLASS_DATA (sym)->as || sym->assoc->rankguessed))
+	   && CLASS_DATA (sym) && !CLASS_DATA (sym)->as)
 	{
 	  if (!CLASS_DATA (sym)->as)
 	CLASS_DATA (sym)->as = gfc_get_array_spec ();
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 1c7ea900ea1..e1c75e9fe02 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7934,7 +7934,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
 	  else
 	tmp = se->string_length;
 
-	  if (expr->ts.deferred && VAR_P (expr->ts.u.cl->b