Re: insight needed on trans-* hacking

2024-12-13 Thread Steve Kargl
On Fri, Dec 13, 2024 at 10:54:03PM +0100, Mikael Morin wrote:
> Le 13/12/2024 à 21:55, Steve Kargl a écrit :
> > On Mon, Dec 09, 2024 at 06:39:19PM -0800, Steve Kargl wrote:
> > > 
> > > I've an almost complete implementation of F_C_STRING,
> > > but need a bit of insight on the inlining that I'm
> > > trying to implement.  In pseudo-code, F_C_STRING is
> > > 
> > > case 1.  f_c_string(string)   = trim(string) // c_null_char
> > > case 2.  f_c_string(string, asis=.false.) = trim(string) // c_null_char
> > > case 3.  f_c_string(string, asis=.true.)  = string   // c_null_char
> > > 
> > 
> > Here's where I'm stuck.
> > 
> FX's message gave most of the information.
> More explicitly, what's missing is roughly:

Thanks, Mikael.  FX's message is/was indeed
helpful, but it seems I am/was getting confused
with gfc_se and stmtblock_t entities.  Once I 
got rid of errors of trying to add an 'gfc_se *'
or tree to a non-existent member of a block, I
would always get the else_branch (as if the
conditional was always false).

-- 
steve


[Fortran, Patch, PR117347, v1] Fix array constructor not resolved in associate

2024-12-13 Thread Andre Vehreschild
Hi all,

attached patch fixes an reject-valid of an array constructor in an associate by
resolving the array constructor before parsing the associate-block. I am not
100% sure, if that is the right place to do this. But given, that there is
already a special casing before the patch, I just propose to do the resolve
there.

Regstests ok on x86_64-pc-linux-gnu / F41. Ok for mainline ?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 0c5315e0d70da9dd107e6057716ff0d4ce89dc9b Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 13 Dec 2024 09:06:11 +0100
Subject: [PATCH] Fortran: Fix associate with derived type array construtor
 [PR117347]

gcc/fortran/ChangeLog:

	PR fortran/117347

	* primary.cc (gfc_match_varspec): Resolve array constructors in
	associate before parsing the block of the associate.

gcc/testsuite/ChangeLog:

	* gfortran.dg/associate_71.f90: New test.
---
 gcc/fortran/primary.cc |  6 +
 gcc/testsuite/gfortran.dg/associate_71.f90 | 28 ++
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/associate_71.f90

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 1db27929eeb..8d6195303a2 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2285,6 +2285,12 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
   if (tgt_expr->rank)
 	sym->ts.u.derived = tgt_expr->ts.u.derived;
 }
+  else if (sym->ts.type == BT_UNKNOWN && sym->assoc && !sym->assoc->dangling
+	   && tgt_expr->expr_type == EXPR_ARRAY)
+{
+  gcc_assert (gfc_resolve_expr (tgt_expr));
+  sym->ts = tgt_expr->ts;
+}

   peeked_char = gfc_peek_ascii_char ();
   if ((inferred_type && !sym->as && peeked_char == '(')
diff --git a/gcc/testsuite/gfortran.dg/associate_71.f90 b/gcc/testsuite/gfortran.dg/associate_71.f90
new file mode 100644
index 000..716d1b8ff61
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_71.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! Check that pr117347 is fixed.
+! Contributed by Ivan Pribec  
+
+program pr117347
+  implicit none
+
+  type :: point
+ real :: x = 42.
+  end type point
+
+  type(point) :: mypoint
+  real:: pi(1)
+  associate (points =>  mypoint ) ! accepted
+pi(:) = points% x
+  end associate
+  if (any(pi /= 42)) stop 1
+  associate (points => (mypoint)) ! accepted
+pi(:) = points% x
+  end associate
+  if (any(pi /= 42)) stop 2
+  associate (points => [mypoint]) ! REJECTED
+pi(:) = points% x
+  end associate
+  if (any(pi /= 42)) stop 3
+end program
+
--
2.47.1



[Fortran, Patch, PR114612, v1] Fix missing deep-copy for allocatable components of derived types having cycles.

2024-12-13 Thread Andre Vehreschild
Hi all,

attached patch fixes deep-copying (or rather its former absence) for
allocatable components of derived types having cyclic dependencies.

Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 4721060d14920335c1b50816d93196c847064ebe Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 13 Dec 2024 12:07:01 +0100
Subject: [PATCH] Fortran: Ensure deep copy of allocatable components in cylic
 types [PR114612]

gcc/fortran/ChangeLog:

	PR fortran/114612

	* trans-array.cc (structure_alloc_comps): Ensure deep copy is
	also done for types having cycles.

gcc/testsuite/ChangeLog:

	* gfortran.dg/alloc_comp_deep_copy_4.f03: New test.
---
 gcc/fortran/trans-array.cc|  7 ++---
 .../gfortran.dg/alloc_comp_deep_copy_4.f03| 29 +++
 2 files changed, 32 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/alloc_comp_deep_copy_4.f03

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 366127d5651..bec14ec254c 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10583,10 +10583,9 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
 	   false, false, NULL_TREE, NULL_TREE);
 	  gfc_add_expr_to_block (&fnblock, tmp);
 	}
-	  else if ((c->attr.allocatable)
-		&& !c->attr.proc_pointer && !same_type
-		&& (!(cmp_has_alloc_comps && c->as) || c->attr.codimension
-			|| caf_in_coarray (caf_mode)))
+	  else if (c->attr.allocatable && !c->attr.proc_pointer
+		   && (!(cmp_has_alloc_comps && c->as) || c->attr.codimension
+		   || caf_in_coarray (caf_mode)))
 	{
 	  rank = c->as ? c->as->rank : 0;
 	  if (c->attr.codimension)
diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_deep_copy_4.f03 b/gcc/testsuite/gfortran.dg/alloc_comp_deep_copy_4.f03
new file mode 100644
index 000..3c445be032f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/alloc_comp_deep_copy_4.f03
@@ -0,0 +1,29 @@
+!{ dg-do run }
+!
+! Contributed Vladimir Terzi  
+! Check that deep-copy for b=a works.
+
+program pr114672
+type node
+integer::val
+type(node),allocatable::next
+end type
+
+type(node)::a,b
+
+allocate(a%next)
+a%val=1
+a%next%val=2
+!print*,a%val,a%next%val
+b=a
+b%val=3
+b%next%val=4
+if (loc(b) == loc(a)) stop 1
+if (loc(b%next) == loc(a%next)) stop 2
+!print*,a%val,a%next%val
+deallocate(b%next)
+if (.NOT. allocated(a%next)) stop 3
+!print*,a%val,a%next%val
+deallocate(a%next)
+end
+
--
2.47.1



Re: insight needed on trans-* hacking

2024-12-13 Thread Steve Kargl
On Mon, Dec 09, 2024 at 06:39:19PM -0800, Steve Kargl wrote:
> 
> I've an almost complete implementation of F_C_STRING,
> but need a bit of insight on the inlining that I'm
> trying to implement.  In pseudo-code, F_C_STRING is
> 
> case 1.  f_c_string(string)   = trim(string) // c_null_char
> case 2.  f_c_string(string, asis=.false.) = trim(string) // c_null_char
> case 3.  f_c_string(string, asis=.true.)  = string   // c_null_char
> 

Here's where I'm stuck.

  if (asis)
{
  /* f_c_string(string, .true.) = string // c_null_char  */

  len = fold_build2_loc (input_location, PLUS_EXPR, cnode,
 fold_convert (cnode, lse.string_length),
 fold_convert (cnode, rse.string_length));

  var = gfc_conv_string_tmp (se, pchar_type_node, len);
  tmp = build_call_expr_loc (input_location, gfor_fndecl_concat_string,
 6, len, var, 
 lse.string_length, lse.expr,
 rse.string_length, rse.expr);

//  
///* f_c_string(string, .false.) = trim(string) // c_null_char  */
//
//gfc_init_se (&tse, se);
//conv_trim (&tse, &lse);
//gfc_add_block_to_block (&se->pre, &tse.pre);
//
//len = fold_build2_loc (input_location, PLUS_EXPR, cnode,
//   fold_convert (cnode, tse.string_length),
//   fold_convert (cnode, rse.string_length));
//var = gfc_conv_string_tmp (se, pchar_type_node, len);
//tmp = build_call_expr_loc (input_location, gfor_fndecl_concat_string,
//   6, len, var, 
//   tse.string_length, tse.expr,
//   rse.string_length, rse.expr);


  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = var;
  se->string_length = len;
}
  else

gfortran needs to select either uncommented code or the code,
based on the whether 'asis' is .true. or .false.  I've been
unable to suss out how to set up the conditional.  (It's been
too long since I hacked in the trans-* files.)

Any suggestions?

-- 
Steve


Re: insight needed on trans-* hacking

2024-12-13 Thread Mikael Morin

Le 13/12/2024 à 21:55, Steve Kargl a écrit :

On Mon, Dec 09, 2024 at 06:39:19PM -0800, Steve Kargl wrote:


I've an almost complete implementation of F_C_STRING,
but need a bit of insight on the inlining that I'm
trying to implement.  In pseudo-code, F_C_STRING is

case 1.  f_c_string(string)   = trim(string) // c_null_char
case 2.  f_c_string(string, asis=.false.) = trim(string) // c_null_char
case 3.  f_c_string(string, asis=.true.)  = string   // c_null_char



Here's where I'm stuck.


FX's message gave most of the information.
More explicitly, what's missing is roughly:


   if (asis)
{
  /* f_c_string(string, .true.) = string // c_null_char  */


gfc_init_block (&block);


  len = fold_build2_loc (input_location, PLUS_EXPR, cnode,
 fold_convert (cnode, lse.string_length),
 fold_convert (cnode, rse.string_length));

  var = gfc_conv_string_tmp (se, pchar_type_node, len);
  tmp = build_call_expr_loc (input_location, gfor_fndecl_concat_string,
 6, len, var,
 lse.string_length, lse.expr,
 rse.string_length, rse.expr);


gfc_add_expr_to_block (&block, tmp);
tree then_branch = gfc_finish_block (&block);

gfc_init_block (&block);

//
///* f_c_string(string, .false.) = trim(string) // c_null_char  */
//
//gfc_init_se (&tse, se);
//conv_trim (&tse, &lse);



//gfc_add_block_to_block (&se->pre, &tse.pre);

s/&se->pre/block/


//
//len = fold_build2_loc (input_location, PLUS_EXPR, cnode,
//   fold_convert (cnode, tse.string_length),
//   fold_convert (cnode, rse.string_length));
//var = gfc_conv_string_tmp (se, pchar_type_node, len);
//tmp = build_call_expr_loc (input_location, gfor_fndecl_concat_string,
//   6, len, var,
//   tse.string_length, tse.expr,
//   rse.string_length, rse.expr);


tree else_branch = gfc_finish_block (&block);

gfc_init_se (&asis_se, se);
gfc_conv_expr (&asis_se, asis);
gfc_add_block_to_block (&se->pre, &asis_se->pre);
gfc_add_block_to_block (&se->???, &asis_se->post);
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 
asis_se.expr, then_branch, else_branch);




  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = var;
  se->string_length = len;
 }
   else

gfortran needs to select either uncommented code or the code,
based on the whether 'asis' is .true. or .false.  I've been
unable to suss out how to set up the conditional.  (It's been
too long since I hacked in the trans-* files.)

Any suggestions?


I hope the above helps.

Mikael


Re: [Fortran, Patch, PR117347, v1] Fix array constructor not resolved in associate

2024-12-13 Thread Harald Anlauf

Hi Andre,

while the patch works with the reduced testcase, it runs into the
newly added gcc_assert() when trying the original testcase in the PR.

I also wonder if this use of gcc_assert() is a good idea or good style:

+  gcc_assert (gfc_resolve_expr (tgt_expr));

Since gcc_assert is a macro, and its precise definition depends on
configuration and could possibly be defined to be a no-op, I suggest
to evaluate arguments with side-effects outside and pass the
return code to gcc_assert.  (There are also many other ways to handle
this situation.

Then removing the gcc_assert around the gfc_resolve_expr() avoids
the ICE, but restores the reported error.

So not OK yet.  Sorry!

Thanks,
Harald


Am 13.12.24 um 10:10 schrieb Andre Vehreschild:

Hi all,

attached patch fixes an reject-valid of an array constructor in an associate by
resolving the array constructor before parsing the associate-block. I am not
100% sure, if that is the right place to do this. But given, that there is
already a special casing before the patch, I just propose to do the resolve
there.

Regstests ok on x86_64-pc-linux-gnu / F41. Ok for mainline ?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de




Re: insight needed on trans-* hacking

2024-12-13 Thread Steve Kargl
On Fri, Dec 13, 2024 at 03:09:57PM -0800, Steve Kargl wrote:
> On Fri, Dec 13, 2024 at 10:54:03PM +0100, Mikael Morin wrote:
> > Le 13/12/2024 à 21:55, Steve Kargl a écrit :
> > > On Mon, Dec 09, 2024 at 06:39:19PM -0800, Steve Kargl wrote:
> > > > 
> > > > I've an almost complete implementation of F_C_STRING,
> > > > but need a bit of insight on the inlining that I'm
> > > > trying to implement.  In pseudo-code, F_C_STRING is
> > > > 
> > > > case 1.  f_c_string(string)   = trim(string) // c_null_char
> > > > case 2.  f_c_string(string, asis=.false.) = trim(string) // c_null_char
> > > > case 3.  f_c_string(string, asis=.true.)  = string   // c_null_char
> > > > 
> > > 
> > > Here's where I'm stuck.
> > > 
> > FX's message gave most of the information.
> > More explicitly, what's missing is roughly:
> 
> Thanks, Mikael.  FX's message is/was indeed
> helpful, but it seems I am/was getting confused
> with gfc_se and stmtblock_t entities.  Once I 
> got rid of errors of trying to add an 'gfc_se *'
> or tree to a non-existent member of a block, I
> would always get the else_branch (as if the
> conditional was always false).
> 

Sigh.  That didn't help.


Mem: 660M Active, 2767M Inact, 56M Laundry, 1292M Wired, 752M Buf, 2914M Free
Swap: 12G Total, 209M Used, 12G Free, 1% Inuse, 120K In

  PID USERNAMETHR PRI NICE   SIZERES STATEC   TIMEWCPU COMMAND
67444 kargl 1  20064T  5932K CPU0 0   0:16 100.07% z
 1478 kargl 5  200   279M35M select   1 241:20   0.64% Xorg
57629 kargl17  200  2452M   127M select   0   0:02   0.59% firefox


I'm fairly certain that 64T bytes should not be needed to append
a character to a string.

I'll take the easy out and implement a library routine. 
-- 
Steve