Re: [Patch, fortran] PR84006 [11/12/13/14/15 Regression] ICE in storage_size() with CLASS entity
Hi Paul, Am 11.05.24 um 08:20 schrieb Paul Richard Thomas: Hi Harald, Thanks for the review. The attached resubmission fixes all the invalid accesses, memory leaks and puts right the incorrect result. In the course of fixing the fix, I found that deferred character length MOLDs gave an ICE because reallocation on assign was using 'dest_word_len' before it was defined. This is fixed by not fixing 'dest_word_len' for these MOLDs. Unfortunately, the same did not work for unlimited polymorphic MOLD expressions and so I added a TODO error in iresolve.cc since it results in all manner of memory errors in runtime. I will return to this another day. A resubmission of the patch for PR113363 will follow since it depends on this one to fix all the memory problems. OK for mainline? this is OK from my side. One minor nit: the updated testcase transfer_class_4.f90 has if (sz /= storage_size (real32)/8) stop 1 I think you meant either storage_size (r) or storage_size (1._real32) instead of checking the storage size of the integer real32 here... Thanks for the patch! Harald Regards Paul On Thu, 9 May 2024 at 08:52, Paul Richard Thomas < paul.richard.tho...@gmail.com> wrote: Hi Harald, The Linaro people caught that as well. Thanks. Interestingly, I was about to re-submit the patch for PR113363, in which all the invalid accesses and memory leaks are fixed but requires this patch to do so. The final transfer was thrown in because it seemed to be working out of the box but should be checked anyway. Inserting your print statements, my test shows the difference in size(chr_a) but prints chr_a as "abcdefgjj" no matter what I do. Needless to say, the latter was the only check that I did. The problem, I suspect, lies somewhere in the murky depths of trans-array.cc(gfc_alloc_allocatable_for_assignment) or in the array part of intrinsic_transfer, untouched by either patch, and is present in 13- and 14-branches. I am onto it. Cheers Paul On Wed, 8 May 2024 at 22:06, Harald Anlauf wrote: Hi Paul, this looks mostly good, but the new testcase transfer_class_4.f90 does exhibit a problem with your patch. Run it with valgrind, or with -fcheck=bounds, or with -fsanitize=address, or add the following around the final transfer: print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) chr_a = transfer (star_a, chr_a) print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) print *, ">", chr_a, "<" This prints for me: 40 40 2 5$ 40 40 4 5$ >abcdefghij^@^@^@^@^@^@^@^@^@^@<$ So since the physical representation of chr_a is sufficient to hold star_a (F2023:16.9.212), no reallocation with a wrong calculated size should happen. (Intel and NAG get this right.) Can you check again? Thanks, Harald
Re: [Patch, fortran] PR84006 [11/12/13/14/15 Regression] ICE in storage_size() with CLASS entity
Hi Harald, Thanks for the review. The attached resubmission fixes all the invalid accesses, memory leaks and puts right the incorrect result. In the course of fixing the fix, I found that deferred character length MOLDs gave an ICE because reallocation on assign was using 'dest_word_len' before it was defined. This is fixed by not fixing 'dest_word_len' for these MOLDs. Unfortunately, the same did not work for unlimited polymorphic MOLD expressions and so I added a TODO error in iresolve.cc since it results in all manner of memory errors in runtime. I will return to this another day. A resubmission of the patch for PR113363 will follow since it depends on this one to fix all the memory problems. OK for mainline? Regards Paul On Thu, 9 May 2024 at 08:52, Paul Richard Thomas < paul.richard.tho...@gmail.com> wrote: > Hi Harald, > > The Linaro people caught that as well. Thanks. > > Interestingly, I was about to re-submit the patch for PR113363, in which > all the invalid accesses and memory leaks are fixed but requires this patch > to do so. The final transfer was thrown in because it seemed to be working > out of the box but should be checked anyway. > > Inserting your print statements, my test shows the difference in > size(chr_a) but prints chr_a as "abcdefgjj" no matter what I do. Needless > to say, the latter was the only check that I did. The problem, I suspect, > lies somewhere in the murky depths of > trans-array.cc(gfc_alloc_allocatable_for_assignment) or in the array part > of intrinsic_transfer, untouched by either patch, and is present in 13- and > 14-branches. > > I am onto it. > > Cheers > > Paul > > > On Wed, 8 May 2024 at 22:06, Harald Anlauf wrote: > >> Hi Paul, >> >> this looks mostly good, but the new testcase transfer_class_4.f90 >> does exhibit a problem with your patch. Run it with valgrind, >> or with -fcheck=bounds, or with -fsanitize=address, or add the >> following around the final transfer: >> >> print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len >> (chr_a) >>chr_a = transfer (star_a, chr_a) >> print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len >> (chr_a) >> print *, ">", chr_a, "<" >> >> This prints for me: >> >>40 40 2 5$ >>40 40 4 5$ >> >abcdefghij^@^@^@^@^@^@^@^@^@^@<$ >> >> So since the physical representation of chr_a is sufficient >> to hold star_a (F2023:16.9.212), no reallocation with a wrong >> calculated size should happen. (Intel and NAG get this right.) >> >> Can you check again? >> >> Thanks, >> Harald >> >> >> diff --git a/gcc/fortran/iresolve.cc b/gcc/fortran/iresolve.cc index c961cdbc2df..c63a4a8d38c 100644 --- a/gcc/fortran/iresolve.cc +++ b/gcc/fortran/iresolve.cc @@ -3025,6 +3025,10 @@ gfc_resolve_transfer (gfc_expr *f, gfc_expr *source ATTRIBUTE_UNUSED, } } + if (UNLIMITED_POLY (mold)) +gfc_error ("TODO: unlimited polymorphic MOLD in TRANSFER intrinsic at %L", + >where); + f->ts = mold->ts; if (size == NULL && mold->rank == 0) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index bc8eb419cff..4590aa6edb4 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -317,6 +317,8 @@ gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size) size = gfc_evaluate_now (size, block); tmp = gfc_evaluate_now (fold_convert (type , tmp), block); } + else + tmp = fold_convert (type , tmp); tmp2 = fold_build2_loc (input_location, MULT_EXPR, type, size, tmp); tmp = fold_build2_loc (input_location, GT_EXPR, @@ -11994,15 +11996,24 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs, /* Take into account _len of unlimited polymorphic entities. TODO: handle class(*) allocatable function results on rhs. */ - if (UNLIMITED_POLY (rhs) && rhs->expr_type == EXPR_VARIABLE) + if (UNLIMITED_POLY (rhs)) { - tree len = trans_get_upoly_len (block, rhs); + tree len; + if (rhs->expr_type == EXPR_VARIABLE) + len = trans_get_upoly_len (block, rhs); + else + len = gfc_class_len_get (tmp); len = fold_build2_loc (input_location, MAX_EXPR, size_type_node, fold_convert (size_type_node, len), size_one_node); size = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (size), size, fold_convert (TREE_TYPE (size), len)); } + else if (rhs->ts.type == BT_CHARACTER && rse->string_length) + size = fold_build2_loc (input_location, MULT_EXPR, +gfc_charlen_type_node, size, +rse->string_length); + tmp = lse->expr; class_han = GFC_CLASS_TYPE_P (TREE_TYPE (tmp)) diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 83041183fcb..80dc3426ab0 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -8250,7 +8250,9 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr) {
Re: [Patch, fortran] PR84006 [11/12/13/14/15 Regression] ICE in storage_size() with CLASS entity
Hi Paul, Am 09.05.24 um 09:52 schrieb Paul Richard Thomas: Hi Harald, Inserting your print statements, my test shows the difference in size(chr_a) but prints chr_a as "abcdefgjj" no matter what I do. have you tried ./a.out | cat -ev ? Or some terminal that shows control characters? Cheers, Harald Needless to say, the latter was the only check that I did. The problem, I suspect, lies somewhere in the murky depths of trans-array.cc(gfc_alloc_allocatable_for_assignment) or in the array part of intrinsic_transfer, untouched by either patch, and is present in 13- and 14-branches. I am onto it. Cheers Paul On Wed, 8 May 2024 at 22:06, Harald Anlauf wrote: Hi Paul, this looks mostly good, but the new testcase transfer_class_4.f90 does exhibit a problem with your patch. Run it with valgrind, or with -fcheck=bounds, or with -fsanitize=address, or add the following around the final transfer: print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) chr_a = transfer (star_a, chr_a) print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) print *, ">", chr_a, "<" This prints for me: 40 40 2 5$ 40 40 4 5$ >abcdefghij^@^@^@^@^@^@^@^@^@^@<$ So since the physical representation of chr_a is sufficient to hold star_a (F2023:16.9.212), no reallocation with a wrong calculated size should happen. (Intel and NAG get this right.) Can you check again? Thanks, Harald Am 08.05.24 um 17:01 schrieb Paul Richard Thomas: This fix is straightforward and described by the ChangeLog. Jose Rui Faustino de Sousa posted the same fix for the ICE on the fortran list slightly more than three years ago. Thinking that he had commit rights, I deferred but, regrettably, the patch was never applied. The attached patch also fixes storage_size and transfer for unlimited polymorphic arguments with character payloads. OK for mainline and backporting after a reasonable interval? Paul Fortran: Unlimited polymorphic intrinsic function arguments [PR84006] 2024-05-08 Paul Thomas gcc/fortran PR fortran/84006 PR fortran/100027 PR fortran/98534 * trans-expr.cc (gfc_resize_class_size_with_len): Use the fold even if a block is not available in which to fix the result. (trans_class_assignment): Enable correct assignment of character expressions to unlimited polymorphic variables using lhs _len field and rse string_length. * trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract the class expression so that the unlimited polymorphic class expression can be used in gfc_resize_class_size_with_len to obtain the storage size for character payloads. Guard the use of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC to prevent the ICE. Also, invert the order to use the class expression extracted from the argument. (gfc_conv_intrinsic_transfer): In same way as 'storage_size', use the _len field to obtaining the correct length for arg 1. gcc/testsuite/ PR fortran/84006 PR fortran/100027 * gfortran.dg/storage_size_7.f90: New test. PR fortran/98534 * gfortran.dg/transfer_class_4.f90: New test.
Re: [Patch, fortran] PR84006 [11/12/13/14/15 Regression] ICE in storage_size() with CLASS entity
Hi Harald, The Linaro people caught that as well. Thanks. Interestingly, I was about to re-submit the patch for PR113363, in which all the invalid accesses and memory leaks are fixed but requires this patch to do so. The final transfer was thrown in because it seemed to be working out of the box but should be checked anyway. Inserting your print statements, my test shows the difference in size(chr_a) but prints chr_a as "abcdefgjj" no matter what I do. Needless to say, the latter was the only check that I did. The problem, I suspect, lies somewhere in the murky depths of trans-array.cc(gfc_alloc_allocatable_for_assignment) or in the array part of intrinsic_transfer, untouched by either patch, and is present in 13- and 14-branches. I am onto it. Cheers Paul On Wed, 8 May 2024 at 22:06, Harald Anlauf wrote: > Hi Paul, > > this looks mostly good, but the new testcase transfer_class_4.f90 > does exhibit a problem with your patch. Run it with valgrind, > or with -fcheck=bounds, or with -fsanitize=address, or add the > following around the final transfer: > > print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len > (chr_a) >chr_a = transfer (star_a, chr_a) > print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len > (chr_a) > print *, ">", chr_a, "<" > > This prints for me: > >40 40 2 5$ >40 40 4 5$ > >abcdefghij^@^@^@^@^@^@^@^@^@^@<$ > > So since the physical representation of chr_a is sufficient > to hold star_a (F2023:16.9.212), no reallocation with a wrong > calculated size should happen. (Intel and NAG get this right.) > > Can you check again? > > Thanks, > Harald > > > Am 08.05.24 um 17:01 schrieb Paul Richard Thomas: > > This fix is straightforward and described by the ChangeLog. Jose Rui > > Faustino de Sousa posted the same fix for the ICE on the fortran list > > slightly more than three years ago. Thinking that he had commit rights, I > > deferred but, regrettably, the patch was never applied. The attached > patch > > also fixes storage_size and transfer for unlimited polymorphic arguments > > with character payloads. > > > > OK for mainline and backporting after a reasonable interval? > > > > Paul > > > > Fortran: Unlimited polymorphic intrinsic function arguments [PR84006] > > > > 2024-05-08 Paul Thomas > > > > gcc/fortran > > PR fortran/84006 > > PR fortran/100027 > > PR fortran/98534 > > * trans-expr.cc (gfc_resize_class_size_with_len): Use the fold > > even if a block is not available in which to fix the result. > > (trans_class_assignment): Enable correct assignment of > > character expressions to unlimited polymorphic variables using > > lhs _len field and rse string_length. > > * trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract > > the class expression so that the unlimited polymorphic class > > expression can be used in gfc_resize_class_size_with_len to > > obtain the storage size for character payloads. Guard the use > > of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC > > to prevent the ICE. Also, invert the order to use the class > > expression extracted from the argument. > > (gfc_conv_intrinsic_transfer): In same way as 'storage_size', > > use the _len field to obtaining the correct length for arg 1. > > > > gcc/testsuite/ > > PR fortran/84006 > > PR fortran/100027 > > * gfortran.dg/storage_size_7.f90: New test. > > > > PR fortran/98534 > > * gfortran.dg/transfer_class_4.f90: New test. > > > >
Re: [Patch, fortran] PR84006 [11/12/13/14/15 Regression] ICE in storage_size() with CLASS entity
Hi Paul, this looks mostly good, but the new testcase transfer_class_4.f90 does exhibit a problem with your patch. Run it with valgrind, or with -fcheck=bounds, or with -fsanitize=address, or add the following around the final transfer: print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) chr_a = transfer (star_a, chr_a) print *, storage_size (star_a), storage_size (chr_a), size (chr_a), len (chr_a) print *, ">", chr_a, "<" This prints for me: 40 40 2 5$ 40 40 4 5$ >abcdefghij^@^@^@^@^@^@^@^@^@^@<$ So since the physical representation of chr_a is sufficient to hold star_a (F2023:16.9.212), no reallocation with a wrong calculated size should happen. (Intel and NAG get this right.) Can you check again? Thanks, Harald Am 08.05.24 um 17:01 schrieb Paul Richard Thomas: This fix is straightforward and described by the ChangeLog. Jose Rui Faustino de Sousa posted the same fix for the ICE on the fortran list slightly more than three years ago. Thinking that he had commit rights, I deferred but, regrettably, the patch was never applied. The attached patch also fixes storage_size and transfer for unlimited polymorphic arguments with character payloads. OK for mainline and backporting after a reasonable interval? Paul Fortran: Unlimited polymorphic intrinsic function arguments [PR84006] 2024-05-08 Paul Thomas gcc/fortran PR fortran/84006 PR fortran/100027 PR fortran/98534 * trans-expr.cc (gfc_resize_class_size_with_len): Use the fold even if a block is not available in which to fix the result. (trans_class_assignment): Enable correct assignment of character expressions to unlimited polymorphic variables using lhs _len field and rse string_length. * trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract the class expression so that the unlimited polymorphic class expression can be used in gfc_resize_class_size_with_len to obtain the storage size for character payloads. Guard the use of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC to prevent the ICE. Also, invert the order to use the class expression extracted from the argument. (gfc_conv_intrinsic_transfer): In same way as 'storage_size', use the _len field to obtaining the correct length for arg 1. gcc/testsuite/ PR fortran/84006 PR fortran/100027 * gfortran.dg/storage_size_7.f90: New test. PR fortran/98534 * gfortran.dg/transfer_class_4.f90: New test.