Re: insight needed on trans-* hacking
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
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.
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
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
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
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
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