Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]
On 10/11/23 12:39 PM, Harald Anlauf wrote: Dear All, the attached trivial patch fixes (= catches) a forgotten corner-case in the detection of a name conflict between an internal procedure and a local declaration for the case that the latter is a derived type. Another torture test by Gerhard... ;-) Used to ICE previously. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald This one is OK Harald. Thanks, Jerry
Re: [PATCH] Fortran: name conflict between internal procedure and derived type [PR104351]
On 10/11/23 12:44 PM, Harald Anlauf wrote: Dear All, sorry for attaching the wrong patch - this time it is the correct one! Harald On 10/11/23 21:39, Harald Anlauf wrote: Dear All, the attached trivial patch fixes (= catches) a forgotten corner-case in the detection of a name conflict between an internal procedure and a local declaration for the case that the latter is a derived type. Another torture test by Gerhard... ;-) Used to ICE previously. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald This one is OK as well. Once I found the right patch on the right email. Regardless, both good to go. Thanks, Jerry
Re: [PATCH] Fortran: out of bounds access with nested implied-do IO [PR111837]
On 10/16/23 12:11 PM, Harald Anlauf wrote: Dear All, the attached patch fixes a dependency check in frontend optimzation for nested implied-do IO. The problem appeared for >= 3 loops only as the check considered dependencies to be only of band form instead of triangular form. Regtested on x86_64-pc-linux-gnu. OK for mainline? As this fixes a regression since 8-release, I plan to backport to all active branches. Thanks, Harald OK for Mainline and backport Thanks Harald Jerry
Re: [PATCH] Fortran: improve checks of NULL without MOLD as actual argument [PR104819]
On 2/29/24 12:56 PM, Harald Anlauf wrote: Dear all, here's a first patch addressing issues with NULL as actual argument: if the dummy is assumed-rank or assumed length, MOLD shall be present. There is also an interp on interoperability of c_sizeof and NULL pointers, for which we have a partially incorrect testcase (gfortran.dg/pr101329.f90) which gets fixed. See https://j3-fortran.org/doc/year/22/22-101r1.txt for more. Furthermore, nested NULL()s are now handled. Regtested on x86_64-pc-linux-gnu. OK for mainline? I consider this part as safe and would like to backport to 13-branch. Objections? Thanks, Harald Looks good to me. I think backport is OK as well. Jerry -
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 3/1/24 11:24 AM, rep.dot@gmail.com wrote: Hi Jerry and Steve, On 29 February 2024 19:28:19 CET, Jerry D wrote: On 2/29/24 10:13 AM, Steve Kargl wrote: On Thu, Feb 29, 2024 at 09:36:43AM -0800, Jerry D wrote: On 2/29/24 1:47 AM, Bernhard Reutner-Fischer wrote: And, just for my own education, the length limitation of iomsg to 255 chars is not backed by the standard AFAICS, right? It's just our STRERR_MAXSZ? Yes, its what we have had for a long lone time. Once you throw an error things get very processor dependent. I found MSGLEN set to 100 and IOMSG_len to 256. Nothing magic about it. There is no restriction on the length for the iomsg-variable that receives the generated error message. In fact, if the iomsg-variable has a deferred-length type parameter, then (re)-allocation to the exact length is expected. F2023 12.11.6 IOMSG= specifier If an error, end-of-file, or end-of-record condition occurs during execution of an input/output statement, iomsg-variable is assigned an explanatory message, as if by intrinsic assignment. If no such condition occurs, the definition status and value of iomsg-variable are unchanged. character(len=23) emsg read(fd,*,iomsg=emsg) Here, the generated iomsg is either truncated to a length of 23 or padded with blanks to a length of 23. character(len=:), allocatable :: emsg read(fd,*,iomsg=emsg) Here, emsg should have the length of whatever error message was generated. HTH Well, currently, if someone uses a larger string than 256 we are going to chop it off. Do we want to process this differently now? Yes. There is some odd hunk about discrepancy of passed len and actual len afterwards in 22-007-r1, IIRC. Didn't look closely though. --- snip --- Attached is the revised patch using the already available string_len_trim function. This hunk is only executed if a user has not passed an iostat or iomsg variable in the parent I/O statement and an error is triggered which terminates execution of the program. In this case, the iomsg string is provided in the usual error message in a "processor defined" way. (F2023): 12.6.4.8.3 Executing defined input/output data transfers --- 11 If the iostat argument of the defined input/output procedure has a nonzero value when that procedure returns, and the processor therefore terminates execution of the program as described in 12.11, the processor shall make the value of the iomsg argument available in a processor-dependent manner. --- OK for trunk? Regards, Jerry commit 51a24ace512e96b425bcde46c056e816c4606784 Author: Jerry DeLisle Date: Mon Mar 4 18:45:49 2024 -0800 Fortran: Add user defined error messages for UDTIO. The defines IOMSG_LEN and MSGLEN were redundant so these are combined into IOMSG_LEN as defined in io.h. The remainder of the patch adds checks for when a user defined derived type IO procedure sets the IOSTAT or IOMSG variables independent of the librrary defined I/O messages. PR libfortran/105456 libgfortran/ChangeLog: * io/io.h (IOMSG_LEN): Moved to here. * io/list_read.c (MSGLEN): Removed MSGLEN. (convert_integer): Changed MSGLEN to IOMSG_LEN. (parse_repeat): Likewise. (read_logical): Likewise. (read_integer): Likewise. (read_character): Likewise. (parse_real): Likewise. (read_complex): Likewise. (read_real): Likewise. (check_type): Likewise. (list_formatted_read_scalar): Adjust to IOMSG_LEN. (nml_read_obj): Add user defined error message. * io/transfer.c (unformatted_read): Add user defined error message. (unformatted_write): Add user defined error message. (formatted_transfer_scalar_read): Add user defined error message. (formatted_transfer_scalar_write): Add user defined error message. * io/write.c (list_formatted_write_scalar): Add user defined error message. (nml_write_obj): Add user defined error message. gcc/testsuite/ChangeLog: * gfortran.dg/pr105456-nmlr.f90: New test. * gfortran.dg/pr105456-nmlw.f90: New test. * gfortran.dg/pr105456-ruf.f90: New test. * gfortran.dg/pr105456-wf.f90: New test. * gfortran.dg/pr105456-wuf.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 b/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 new file mode 100644 index 000..5ce5d082133 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +! { dg-shouldfail "The users message" } +module m + implicit none + type :: t +character :: c +integer :: k + contains +procedure :: write_formatted +generic :: write(formatted) => write_formatted +procedure :: read_formatt
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 3/5/24 1:51 PM, Harald Anlauf wrote: Hi Jerry, on further thought, do we sanitize 'child_iomsg'? We pass it to snprintf as format. Wouldn't a strncpy be sufficient? Harald Just to be safe I will bump char message[IOMSG_LEN] to char message[IOMSG_LEN + 1] This is like a C string vs a Fortran string length situation. snprintf guarantees we don't exceed the child_iomsg_len and null terminates it. I added 1 to: child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg) + 1 Because snprintf was chopping off the last character of the fortran string to put the null in. (zero based vs one based char array). I test this with a very long string which exceeded the length and then reduced it until I could see the desired end. I have not tried running a test case with sanitize. I did check with valgrind. I will try the sanitize flags to see if we get a problem. If not will push. Thanks for comments, Jerry - On 3/5/24 22:37, Harald Anlauf wrote: Hi Jerry, I think there is the risk of buffer overrun in the following places: + char message[IOMSG_LEN]; + child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg) + 1; free_line (dtp); snprintf (message, child_iomsg_len, child_iomsg); generate_error (&dtp->common, dtp->u.p.child_saved_iostat, plus several more. Wouldn't it be better to increase the size of message by one? Thanks, Harald On 3/5/24 04:15, Jerry D wrote: On 3/1/24 11:24 AM, rep.dot@gmail.com wrote: Hi Jerry and Steve, On 29 February 2024 19:28:19 CET, Jerry D wrote: On 2/29/24 10:13 AM, Steve Kargl wrote: On Thu, Feb 29, 2024 at 09:36:43AM -0800, Jerry D wrote: On 2/29/24 1:47 AM, Bernhard Reutner-Fischer wrote: And, just for my own education, the length limitation of iomsg to 255 chars is not backed by the standard AFAICS, right? It's just our STRERR_MAXSZ? Yes, its what we have had for a long lone time. Once you throw an error things get very processor dependent. I found MSGLEN set to 100 and IOMSG_len to 256. Nothing magic about it. There is no restriction on the length for the iomsg-variable that receives the generated error message. In fact, if the iomsg-variable has a deferred-length type parameter, then (re)-allocation to the exact length is expected. F2023 12.11.6 IOMSG= specifier If an error, end-of-file, or end-of-record condition occurs during execution of an input/output statement, iomsg-variable is assigned an explanatory message, as if by intrinsic assignment. If no such condition occurs, the definition status and value of iomsg-variable are unchanged. character(len=23) emsg read(fd,*,iomsg=emsg) Here, the generated iomsg is either truncated to a length of 23 or padded with blanks to a length of 23. character(len=:), allocatable :: emsg read(fd,*,iomsg=emsg) Here, emsg should have the length of whatever error message was generated. HTH Well, currently, if someone uses a larger string than 256 we are going to chop it off. Do we want to process this differently now? Yes. There is some odd hunk about discrepancy of passed len and actual len afterwards in 22-007-r1, IIRC. Didn't look closely though. --- snip --- Attached is the revised patch using the already available string_len_trim function. This hunk is only executed if a user has not passed an iostat or iomsg variable in the parent I/O statement and an error is triggered which terminates execution of the program. In this case, the iomsg string is provided in the usual error message in a "processor defined" way. (F2023): 12.6.4.8.3 Executing defined input/output data transfers --- 11 If the iostat argument of the defined input/output procedure has a nonzero value when that procedure returns, and the processor therefore terminates execution of the program as described in 12.11, the processor shall make the value of the iomsg argument available in a processor-dependent manner. --- OK for trunk? Regards, Jerry
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 3/6/24 9:13 AM, Harald Anlauf wrote: Hi Jerry, can you please replace the user message in e.g. your new testcase pr105456-wf.f90 by say: piomsg="The users message containing % and %% and %s and other stuff" This behaves as expected with Intel, but dies horribly with gfortran after your patch! Cheers, Harald Fixed with: commit 03932d3203bce244edd812b81921c2f16ea18d86 (HEAD -> master, origin/master, origin/HEAD) Author: Jerry DeLisle Date: Wed Mar 6 19:46:04 2024 -0800 Fortran: Fix issue with using snprintf function. The previous patch used snprintf to set the message string. The message string is not a formatted string and the snprintf will interpret '%' related characters as format specifiers when there are no associated output variables. A segfault ensues. This change replaces snprintf with a fortran string copy function and null terminates the message string. PR libfortran/105456 libgfortran/ChangeLog: * io/list_read.c (list_formatted_read_scalar): Use fstrcpy from libgfortran/runtime/string.c to replace snprintf. (nml_read_obj): Likewise. * io/transfer.c (unformatted_read): Likewise. (unformatted_write): Likewise. (formatted_transfer_scalar_read): Likewise. (formatted_transfer_scalar_write): Likewise. * io/write.c (list_formatted_write_scalar): Likewise. (nml_write_obj): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/pr105456.f90: Revise using '%' characters in users error message. Jerry -
[patch, libgfortran] PR107031 - endfile truncates file at wrong position
Hi all, There has been a bit of discussio on which way to go on this. I took a look today and this trivial patch gives the behavior concluded on Fortran Discourse. See the bugzilla for all the relevant information. Regresion tested on x86-64. I will do the appropriate changelog. OK for trunk? Attached is a new test case and the patch here: diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c index 2bc05b293f8..d169961f997 100644 --- a/libgfortran/io/file_pos.c +++ b/libgfortran/io/file_pos.c @@ -352,7 +352,6 @@ st_endfile (st_parameter_filepos *fpp) dtp.common = fpp->common; memset (&dtp.u.p, 0, sizeof (dtp.u.p)); dtp.u.p.current_unit = u; - next_record (&dtp, 1); } unit_truncate (u, stell (u->s), &fpp->common); ! { dg-do run } ! PR107031 Check that endfile truncates at end of record 5. program test_truncate integer :: num_rec, tmp, i, nr, j open(10, file="in.dat", action='readwrite') do i=1,10 write(10, *) i end do rewind (10) num_rec = 5 i = 1 ioerr = 0 do while (i <= num_rec .and. ioerr == 0) read(10, *, iostat=ioerr) tmp i = i + 1 enddo endfile(10) rewind (10) i = 0 ioerr = 0 do while (i <= num_rec + 1 .and. ioerr == 0) read(10, *, iostat=ioerr) j i = i + 1 end do close(10, status='delete') if (i - 1 /= 5) stop 1 end program test_truncate
Re: [PATCH] Fortran: fix DATA and derived types with pointer components [PR114474]
On 3/27/24 1:42 PM, Harald Anlauf wrote: Dear all, the attached patch fixes a 10+ regression for cases where a derived type with a pointer component is used in a DATA statement. The failure looked obscure, see testcase comments, and pointed to a possible issue in the resolution (order). For the failing test, the target variable was seen with ts.type == BT_PROCEDURE instead of its actual type. For this reason, I restricted the fixup as much as possible. For details, please see the commit message. Testcase cross-checked with NAG. Regtested on x86_64-pc-linux-gnu. OK for mainline? If this fix survives broader testing, I would like to backport. Thanks, Harald P.S.: while trying to extend coverage of conforming code, I had much fun also with other compilers (e.g. NAG panicking...) OK, for trunk and we will see how it survives for a bit before back port. Jerry -
[patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
Hi all, The attached log entry and patch (git show) fixes this issue by adding logic to handle spaces in eat_separators. One or more spaces by themselves are a valid separator. So in this case we look at the character following the spaces to see if it is a comma or semicolon. If so, I change it to the valid separator for the given decimal mode, point or comma. This allows the comma or semicolon to be interpreted as a null read on the next effective item in the formatted read. I chose a permissive approach here that allows reads to proceed when the input line is mal-formed with an incorrect separator as long as there is at least one space in front of it. New test case included. Regression tested on X86-64. OK for trunk? Backport to 13 after some time. Regards, Jerrycommit 7d1a958d6b099ea88b6c51649baf5dbd5e598909 Author: Jerry DeLisle Date: Wed Apr 3 18:07:30 2024 -0700 libfortran: Fix handling of formatted separators. PR libfortran/114304 libgfortran/ChangeLog: * io/list_read.c (eat_separator): Add logic to handle spaces preceding a comma or semicolon such that that a 'null' read occurs without error at the end of comma or semicolon terminated input lines. gcc/testsuite/ChangeLog: * gfortran.dg/pr114304.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr114304.f90 b/gcc/testsuite/gfortran.dg/pr114304.f90 new file mode 100644 index 000..57af619246b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr114304.f90 @@ -0,0 +1,49 @@ +! { dg-do run } +! pr114304 +real :: x(3) +character(len=1) :: s +integer :: ios + +s = 'x' + +open(99, decimal="comma", status='scratch') +write(99, '(a)') '1,23435 1243,24 13,24 a' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'a') stop 1 + +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24;a' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'a') stop 2 + +! Note: not reading 's' +rewind(99) +write(99, '(a)') '1,23435 1243,24 13,24 ,' +rewind(99) +read(99, *) x +if (ios /= 0) stop 3 + +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24 ,' +rewind(99) +read(99, *, iostat=ios) x +if (ios /= 0) stop 4 + +! Now reading 's' +s = 'w' +rewind(99) +write(99, '(a)') '1,23435 1243,24 13,24 ,' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'w') stop 5 + +s = 'w' +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24 ,' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'w') stop 6 +close(99) +end diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index fb3f7dbc34d..f6f169043bf 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -461,11 +461,30 @@ eat_separator (st_parameter_dt *dtp) int c, n; int err = 0; - eat_spaces (dtp); dtp->u.p.comma_flag = 0; + c = next_char (dtp); + if (c == ' ') +{ + eat_spaces (dtp); + c = next_char (dtp); + if (c == ',') + { + if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) + unget_char (dtp, ';'); + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + return err; + } + if (c == ';') + { + if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT) + unget_char (dtp, ','); + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + return err; + } +} - if ((c = next_char (dtp)) == EOF) -return LIBERROR_END; switch (c) { case ',': @@ -476,7 +495,10 @@ eat_separator (st_parameter_dt *dtp) unget_char (dtp, c); break; } -/* Fall through. */ + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + break; + case ';': dtp->u.p.comma_flag = 1; eat_spaces (dtp);
Re: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
On 4/4/24 2:31 AM, Tobias Burnus wrote: Hi Jerry, Jerry D wrote: The attached log entry and patch (git show) fixes this issue by adding logic to handle spaces in eat_separators. One or more spaces by themselves are a valid separator. So in this case we look at the character following the spaces to see if it is a comma or semicolon. If so, I change it to the valid separator for the given decimal mode, point or comma. This allows the comma or semicolon to be interpreted as a null read on the next effective item in the formatted read. I chose a permissive approach here that allows reads to proceed when the input line is mal-formed with an incorrect separator as long as there is at least one space in front of it. First: Consider also adding 'PR fortran/105473' to the commit log as the PRs are closely related, albeit this PR is different- The patch looks mostly like I would expect, except for decimal='point' and a ';' which is *not* preceded by a space. Thanks for working on it. Regarding the 'except' case: * * * If I try your patch with the testcase of at comment 19, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114304#c19 → https://gcc.gnu.org/bugzilla/attachment.cgi?id=57695 , I do note that with 'decimal=point', a tailing semicolon is silently accepted – even if not proceeded by a space. I did that on purpose out of leniency and fear of breaking something. I will add that in and do some testing. I think such code is invalid – and you could consider to reject it. Otherwise, the handling all seems to be in line with the Fortran spec. i.e. for the following string, I had *expected an error*: I will see what it does. I agree in principle. point, isreal = F , testinput = ";"n= 42 ios= 0 point, isreal = F , testinput = "5;"n= 5 ios= 0 point, isreal = T , testinput = "8;"r= 8. ios= 0 point, isreal = T , testinput = "3.3;"r= 3.2995 ios= 0 point, isreal = T , testinput = "3,3;"r= 3. ios= 0 while I think the following is OK (i.e. no error is what I expect) due to the the space before the ';'. Agree and this is what I was attempting. point, isreal = F , testinput = "7 ;"n= 7 ios= 0 point, isreal = T , testinput = "9 ;"r= 9. ios= 0 point, isreal = T , testinput = "4.4 ;"r= 4.4010 ios=0 point, isreal = T , testinput = "9 ;"r= 9. ios= 0 point, isreal = T , testinput = "4,4 ;"r= 4. ios= 0 * * * Looking at the other compilers, ifort, ifx and Flang do issue an error here. Likewise, g95 seems to yield an error in this case (see below). I do note that the Lapack testcase that triggered this PR did have such a code - but it was then changed because g95 did not like it: https://github.com/Reference-LAPACK/lapack/commit/64e8a7500d817869e5fcde35afd39af8bc7a8086 I am glad they fixed that, it triggered a whole lot of cycles here. In terms of gfortran: until recently did accept it (all versions, including 13+14); it then rejected it due to the change in PR105473 (GCC 14/mainline, backported to 13)– but I now think it rightly did so. With the current patch, it is accepted again. * * * I have attached the modified testcase linked above; consider adding it as well. - Changes to the one of the attachment: - I added a few additional (albeit boring) tests - I added an expected output + error diagnostic. The testcase assumes an error for ';' as separator (with 'point'), unless there is a space before it. [If we want to not diagnose this as vendor extension, we really need to add a comment to that testcase besides changing valid = .false. to .true.] I have gone back and forth on this issue many times trying to find the middle ground. The standard is fairly clear. To me it is on the user to not use malformed input so allowing with the intervening space we are simply ignoring the trailing ',' or ';' and calling the spaces sufficient as a valid separator. Regardless I now have your modified test case passing. Much appreciated. Thanks for the reviews. I will resubmit when I can, hopefully today. Cheers, Jerry
Re: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
On 4/4/24 2:31 AM, Tobias Burnus wrote: Hi Jerry, --- snip --- The patch looks mostly like I would expect, except for decimal='point' and a ';' which is *not* preceded by a space. Thanks for working on it. Regarding the 'except' case: --- snip --- i.e. for the following string, I had *expected an error*: point, isreal = F , testinput = ";"n= 42 ios= 0 point, isreal = F , testinput = "5;"n= 5 ios= 0 point, isreal = T , testinput = "8;"r= 8. ios= 0 point, isreal = T , testinput = "3.3;"r= 3.2995 ios= 0 point, isreal = T , testinput = "3,3;"r= 3. ios= 0 --- snip --- I have attached the modified testcase linked above; consider adding it as well. - Changes to the one of the attachment: - I added a few additional (albeit boring) tests - I added an expected output + error diagnostic. The testcase assumes an error for ';' as separator (with 'point'), unless there is a space before it. --- snip --- Here attached is the revised patch. I replaced the new test case I had with the one you provided modified and it now passes. I modified the test case pr105473.f90 to expect the error on semicolon. Regression tested on X86_64. OK for trunk and a bit later back port to 13? Cheers, Jerry commit 9c8318cd8703d49ad7563e89765f8849ebc14385 Author: Jerry DeLisle Date: Thu Apr 4 13:48:20 2024 -0700 libfortran: Fix handling of formatted separators. PR libfortran/114304 PR libfortran/105473 libgfortran/ChangeLog: * io/list_read.c (eat_separator): Add logic to handle spaces preceding a comma or semicolon such that that a 'null' read occurs without error at the end of comma or semicolon terminated input lines. Add check and error message for ';'. gcc/testsuite/ChangeLog: * gfortran.dg/pr105473.f90: Modify to verify new error message. * gfortran.dg/pr114304.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr105473.f90 b/gcc/testsuite/gfortran.dg/pr105473.f90 index 2679f6bb447..863a312c794 100644 --- a/gcc/testsuite/gfortran.dg/pr105473.f90 +++ b/gcc/testsuite/gfortran.dg/pr105473.f90 @@ -9,11 +9,11 @@ n = 999; m = 777; r=1.2345 z = cmplx(0.0,0.0) -! Check that semi-colon is allowed as separator with decimal=point. +! Check that semi-colon is not allowed as separator with decimal=point. ios=0 testinput = '1;17;3.14159' read(testinput,*,decimal='point',iostat=ios) n, m, r - if (ios /= 0) stop 1 + if (ios /= 5010) stop 1 ! Check that semi-colon allowed as a separator with decimal=point. ios=0 diff --git a/gcc/testsuite/gfortran.dg/pr114304.f90 b/gcc/testsuite/gfortran.dg/pr114304.f90 new file mode 100644 index 000..8344a9ea857 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr114304.f90 @@ -0,0 +1,101 @@ +! { dg-do run } +! +! PR fortran/114304 +! +! See also PR fortran/105473 +! +! Testing: Does list-directed reading an integer/real allow some non-integer input? +! +! Note: GCC result comments before fix of this PR. + + implicit none + call t(.true., 'comma', ';') ! No error shown + call t(.false., 'point', ';') ! /!\ gfortran: no error, others: error + call t(.false., 'comma', ',') ! Error shown + call t(.true., 'point', ',') ! No error shown + call t(.false., 'comma', '.') ! Error shown + call t(.false., 'point', '.') ! Error shown + call t(.false., 'comma', '5.') ! Error shown + call t(.false., 'point', '5.') ! gfortran/flang: Error shown, ifort: no error + call t(.false., 'comma', '5,') ! gfortran: error; others: no error + call t(.true., 'point', '5,') ! No error shown + call t(.true., 'comma', '5;') ! No error shown + call t(.false., 'point', '5;') ! /!\ gfortran: no error shown, others: error + call t(.true., 'comma', '7 .') ! No error shown + call t(.true., 'point', '7 .') ! No error shown + call t(.true., 'comma', '7 ,') ! /!\ gfortran: error; others: no error + call t(.true., 'point', '7 ,') ! No error shown + call t(.true., 'comma', '7 ;') ! No error shown + call t(.true., 'point', '7 ;') ! No error shown + +! print *, '---' + + call t(.false., 'comma', '8.', .true.) ! Error shown + call t(.true., 'point', '8.', .true.) ! gfortran/flang: Error shown, ifort: no error + call t(.true., 'comma', '8,', .true.) ! gfortran: error; others: no error + call t(.true., 'point', '8,', .true.) ! No error shown + call t(.true., 'comma', '8;', .true.) ! No error shown + call t(.false., 'point', '8;', .true.) ! /!\ gfortran: no error shown, others: error + call t(.true., 'comma', '9 .', .true.) ! No error shown + call t(.true., 'point', '9 .', .true.) ! No error shown + call t(.true., 'comma', '9 ,', .true.) ! /!\ gfortran: error; others: no error + call t(.true., 'point', '9 ,', .true.) ! No error shown + call t(.true., 'comma', '9 ;', .true.) ! No error shown + call t(.true., 'point'
Re: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
On 4/4/24 2:41 PM, Tobias Burnus wrote: Hi Jerry, I think for the current testcases, I like the patch – the question is only what's about: ',3' as input for 'comma' (or '.3' as input for 'point') For 'point' – 0.3 is read and ios = 0 (as expected) But for 'comma': * GCC 12 reads nothing and has ios = 0. * GCC 13/mainline has an error (ios != 0 – and reads nothing) * GCC with your patch: Same result: ios != 0 and nothing read. Expected: Same as with ','/'comma' – namely: read-in value is 0.3. → https://godbolt.org/z/4rc8fz4sT for the full example, which works with ifort, ifx and flang * * * Can you check and fix this? It looks perfectly valid to me to have remove the '0' in the floating point numbers '0.3' or '0,3' seems to be permitted – and it works for '.' (with 'point') but not for ',' (with 'comma'). Yes, I found the spot to fix this. F2023's "13.10.3.1 List-directed input forms" refers to "13.7.2.3.2 F editing", which states: "The standard form of the input field [...] The form of the mantissa is an optional sign, followed by a string of one or more digits optionally containing a decimal symbol." The latter does not require that the digit has to be before the decimal sign and as for output, it is optional, it is surely intended that ",3" is a valid floating-point number for decimal='comma'. Agree * * * I extended the testcase to check for this – see attached diff. All 'point' work, all 'comma' fail. Thanks for working on this! Tobias Thanks much. After I fix it, I will use your extended test case in the test suite. Jerry -
Re: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
On 4/5/24 10:47 AM, Jerry D wrote: On 4/4/24 2:41 PM, Tobias Burnus wrote: Hi Jerry, I think for the current testcases, I like the patch – the question is only what's about: ',3' as input for 'comma' (or '.3' as input for 'point') For 'point' – 0.3 is read and ios = 0 (as expected) But for 'comma': * GCC 12 reads nothing and has ios = 0. * GCC 13/mainline has an error (ios != 0 – and reads nothing) * GCC with your patch: Same result: ios != 0 and nothing read. Expected: Same as with ','/'comma' – namely: read-in value is 0.3. → https://godbolt.org/z/4rc8fz4sT for the full example, which works with ifort, ifx and flang * * * Can you check and fix this? It looks perfectly valid to me to have remove the '0' in the floating point numbers '0.3' or '0,3' seems to be permitted – and it works for '.' (with 'point') but not for ',' (with 'comma'). Yes, I found the spot to fix this. F2023's "13.10.3.1 List-directed input forms" refers to "13.7.2.3.2 F editing", which states: "The standard form of the input field [...] The form of the mantissa is an optional sign, followed by a string of one or more digits optionally containing a decimal symbol." The latter does not require that the digit has to be before the decimal sign and as for output, it is optional, it is surely intended that ",3" is a valid floating-point number for decimal='comma'. Agree * * * I extended the testcase to check for this – see attached diff. All 'point' work, all 'comma' fail. Thanks for working on this! Tobias Thanks much. After I fix it, I will use your extended test case in the test suite. Jerry - See attached updated patch. Regressions tested on x86-64. OK for trunk and 13 after a bit. Jerry - commit 690b9fa57d95796ba0e92a172e1490601f25e03a Author: Jerry DeLisle Date: Fri Apr 5 19:25:13 2024 -0700 libfortran: Fix handling of formatted separators. PR libfortran/114304 PR libfortran/105473 libgfortran/ChangeLog: * io/list_read.c (eat_separator): Add logic to handle spaces preceding a comma or semicolon such that that a 'null' read occurs without error at the end of comma or semicolon terminated input lines. Add check and error message for ';'. (list_formatted_read_scalar): Treat comma as a decimal point when specified by the decimal mode on the first item. gcc/testsuite/ChangeLog: * gfortran.dg/pr105473.f90: Modify to verify new error message. * gfortran.dg/pr114304.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr105473.f90 b/gcc/testsuite/gfortran.dg/pr105473.f90 index 2679f6bb447..863a312c794 100644 --- a/gcc/testsuite/gfortran.dg/pr105473.f90 +++ b/gcc/testsuite/gfortran.dg/pr105473.f90 @@ -9,11 +9,11 @@ n = 999; m = 777; r=1.2345 z = cmplx(0.0,0.0) -! Check that semi-colon is allowed as separator with decimal=point. +! Check that semi-colon is not allowed as separator with decimal=point. ios=0 testinput = '1;17;3.14159' read(testinput,*,decimal='point',iostat=ios) n, m, r - if (ios /= 0) stop 1 + if (ios /= 5010) stop 1 ! Check that semi-colon allowed as a separator with decimal=point. ios=0 diff --git a/gcc/testsuite/gfortran.dg/pr114304.f90 b/gcc/testsuite/gfortran.dg/pr114304.f90 new file mode 100644 index 000..2f913f1ab34 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr114304.f90 @@ -0,0 +1,114 @@ +! { dg-do run } +! +! PR fortran/114304 +! +! See also PR fortran/105473 +! +! Testing: Does list-directed reading an integer/real allow some non-integer input? +! +! Note: GCC result comments before fix of this PR. + + implicit none + call t(.true., 'comma', ';') ! No error shown + call t(.false., 'point', ';') ! /!\ gfortran: no error, others: error + call t(.false., 'comma', ',') ! Error shown + call t(.true., 'point', ',') ! No error shown + call t(.false., 'comma', '.') ! Error shown + call t(.false., 'point', '.') ! Error shown + call t(.false., 'comma', '5.') ! Error shown + call t(.false., 'point', '5.') ! gfortran/flang: Error shown, ifort: no error + call t(.false., 'comma', '5,') ! gfortran: error; others: no error + call t(.true., 'point', '5,') ! No error shown + call t(.true., 'comma', '5;') ! No error shown + call t(.false., 'point', '5;') ! /!\ gfortran: no error shown, others: error + call t(.true., 'comma', '7 .') ! No erro
Re: [Patch] Fortran: List-directed read - accept again tab as alternative to space as separator [PR114304]
On 4/8/24 2:53 AM, Tobias Burnus wrote: Jerry D wrote: See attached updated patch. It turned rather quickly out that this patch – committed as r14-9822-g93adf88cc6744a – caused regressions. Namely, real-world code use tab(s) as separator instead of spaces. [For instance, PR114304 which contains a named-list input file from SPEC CPU 2017; that example uses tabs before the '=' sign, but the issue is more generic.] I think the ISO Fortran standard only permits spaces, but as it feels natural and is widely supported, tabs are used and should remain supported. It is not quite clear how '\r' are or should be handled, but as eat_spaces did use it, I thought I would add one testcase using them as well. That test is not affected by my change; it did work before with GCC and still does – but it does fail with ifort/ifx/flang. I have not thought deeply whether it should be supported or not – and looking at the libgfortran source file, it often but (→ testcase) not consistently requires that an \n follows the \r. OK for mainline? [And: When the previous patch gets backported, this surely needs to be included as well.] Tobias Good catch. I did not even think about tabs. OK to commit and I will take care of it when I do the backport to 13. Thanks! Jerry
Re: [Patch, fortran] PR114535 - [13/14 regression] ICE with elemental finalizer
On 4/8/24 2:45 AM, Paul Richard Thomas wrote: Hi All, This one is blazingly 'obvious'. I haven't had the heart to investigate why somebody thought that it is a good idea to check if unreferenced symbols are finalizable because, I suspect, that 'somebody' was me. Worse, I tried a couple of other fixes before I hit on the 'obvious' one :-( The ChangeLog says it all. OK for mainline and then backporting in a couple of weeks? Paul Fortran: Fix ICE in trans-stmt.cc(gfc_trans_call) [PR114535] 2024-04-08 Paul Thomas mailto:pa...@gcc.gnu.org>> gcc/fortran PR fortran/114535 * resolve.cc (resolve_symbol): Remove last chunk that checked for finalization of unreferenced symbols. gcc/testsuite/ PR fortran/114535 * gfortran.dg/pr114535d.f90: New test. * gfortran.dg/pr114535iv.f90: Additional source. Yes, OK Paul. Don't feel bad. It wasn't Tabs. LOL Jerry
Re: [patch, libgfortran] PR111022 ES0.0E0 format gave ES0.dE0 output with d too high.
On 1/30/24 12:36 PM, Harald Anlauf wrote: Hi Jerry, Am 30.01.24 um 19:15 schrieb Jerry D: The attached patch attempts to fix the handling of the EN0.0E0 and ES0.0E0 formatting by correctly calculating the number of digits needed for the exponents and building those exponents into the float string. while your patch addresses ENw.dE0 and ESw.dE0 formatting, it does not fix Ew.dE0, which can be seen with the following test: write(buffer,"(E0.3E0)") .6660_4 print *, buffer write(buffer,"(E0.3)") .6660_4 print *, buffer I get even with your patch: 0.666 0.666 but would have expected: 0.666E+0 ! F2018 & F2023, table 13.1 0.666E+0 ! F2023, table 13.1 Tha attached file shows the complete revised patch and git log generated by using the 'git show' command. I only just discovered that one. (eye roll). Regressions tested on x86-64. OK for trunk? Regards, Jerry commit 95c878a97944f952aef226ff0224b2198abfbe0f Author: Jerry DeLisle Date: Fri Feb 2 18:12:33 2024 -0800 libgfortran: EN0.0E0 and ES0.0E0 format editing. PR libgfortran/111022 F2018 and F2023 standards added zero width exponents. This required additional special handing in the process of building formatted floating point strings. G formatting uses either F or E formatting as documented in write_float.def comments. This logic changes the format token from FMT_G to FMT_F or FMT_E. The new formatting requirements interfere with this process when a FMT_G float string is being built. To avoid this, a new component called 'pushed' is added to the fnode structure to save this condition. The 'pushed' condition is then used to bypass portions of the new ES,E,EN, and D formatting, falling through to the existing default formatting which is retained. libgfortran/ChangeLog: * io/format.c (get_fnode): Update initialization of fnode. (parse_format_list): Initialization. * io/format.h (struct fnode): Added the new 'pushed' component. * io/write.c (select_buffer): Whitespace. (write_real): Whitespace. (write_real_w0): Adjust logic for the d == 0 condition. * io/write_float.def (determine_precision): Whitespace. (build_float_string): Calculate width of ..E0 exponents and adjust logic accordingly. (build_infnan_string): Whitespace. (CALCULATE_EXP): Whitespace. (quadmath_snprintf): Whitespace. (determine_en_precision): Whitespace. gcc/testsuite/ChangeLog: * gfortran.dg/fmt_error_10.f: Show D+0 exponent. * gfortran.dg/pr96436_4.f90: Show E+0 exponent. * gfortran.dg/pr96436_5.f90: Show E+0 exponent. * gfortran.dg/pr111022.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/fmt_error_10.f b/gcc/testsuite/gfortran.dg/fmt_error_10.f index 6e1a5f60bea..fc6620a60a6 100644 --- a/gcc/testsuite/gfortran.dg/fmt_error_10.f +++ b/gcc/testsuite/gfortran.dg/fmt_error_10.f @@ -18,7 +18,7 @@ str = '(1pd0.15)' write (line,str,iostat=istat, iomsg=msg) 1.0d0 - if (line.ne."1.000") STOP 5 + if (line.ne."1.000D+0") STOP 5 read (*,str,iostat=istat, iomsg=msg) x if (istat.ne.5006 .or. msg(1:10).ne."Zero width") STOP 6 if (x.ne.555.25) STOP 7 diff --git a/gcc/testsuite/gfortran.dg/pr111022.f90 b/gcc/testsuite/gfortran.dg/pr111022.f90 new file mode 100644 index 000..eef55ff5ce0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr111022.f90 @@ -0,0 +1,72 @@ +! { dg-do run } +program pr111022 + character(20) :: buffer + write(buffer,"(EN0.3E0)") .6660_4 + if (buffer.ne."666.000E-3") stop 1 + write(buffer,"(EN0.3E0)") 6.660_4 + if (buffer.ne."6.660E+0") stop 2 + write(buffer,"(EN0.3E0)") 66.60_4 + if (buffer.ne."66.600E+0") stop 3 + write(buffer,"(EN0.3E0)") 666.0_4 + if (buffer.ne."666.000E+0") stop 4 + write(buffer,"(EN0.3E0)") 6660.0_4 + if (buffer.ne."6.660E+3") stop 5 + write(buffer,"(EN0.3E0)") 66600.0_4 + if (buffer.ne."66.600E+3") stop 6 + + write(buffer,"(EN0.0E0)") 666.0_4 + if (buffer.ne."666.E+0") stop 7 + write(buffer,"(EN0.0E1)") 666.0_4 + if (buffer.ne."666.E+0") stop 8 + write(buffer,"(EN0.0E2)") 666.0_4 + if (buffer.ne."666.E+00") stop 9 + write(buffer,"(EN0.0E3)") 666.0_4 + if (buffer.ne."666.E+000") stop 10 + write(buffer,"(EN0.0E4)") 666.0_4 + if (buffer.ne."666.E+") stop 11 + write(buffer,"(EN0.0E5)") 666.0_4 + if (buffer.ne."666.E+0") stop 12 + write(buffer,"(EN0.0E6)") 666
Re: [PATCH] Fortran: error recovery on arithmetic overflow on unary operations [PR113799]
On 2/8/24 1:03 PM, Harald Anlauf wrote: Dear all, the attached patch improves error recovery when we encounter an array constructor where a unary operator (e.g. minus) is applied and -frange-check is active. The solution is not to terminate early in that case to avoid inconsistencies between check_result and reduce_unary when such a situation occurs. (There might be similar issues for binary operators, not treated here.) Regtested on x86_64-pc-linux-gnu. OK for mainline? The ICE/memory corruption is actually a 10+ regression. Do we need a backport? Thanks, Harald Hi Harald, This patch looks OK. Thanks, Jerry
[patch, libgfortran] PR109358
The attached patch fixes this PR by properly adjusting some variables When using stream io. See log below. New test case included. Regression tested on x86_64. OK for trunk and backport? Regards, Jerry ChangeLog: libgfortran: Adjust bytes_left and pos for access="STREAM". During tab edits, the pos (position) and bytes_used Variables were not being set correctly for stream I/O. Since stream I/O does not have 'real' records, the format buffer active length must be used instead of the record length variable. libgfortran/ChangeLog: PR libgfortran/109358 * io/transfer.c (formatted_transfer_scalar_write): Adjust bytes_used and pos variable for stream access. gcc/testsuite/ChangeLog: PR libgfortran/109358 * gfortran.dg/pr109358.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr109358.f90 b/gcc/testsuite/gfortran.dg/pr109358.f90 new file mode 100644 index 000..5013984095b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr109358.f90 @@ -0,0 +1,14 @@ +! { dg-do run } +! PR109358, test that tabs during stream io are correct. +program tabs + implicit none + integer :: fd + character(64) :: line + open(newunit=fd, file="otabs.txt", form="formatted", access="stream") + write(fd, "(i4, t40, i4, t20, i5.5)") 1234, , 67890 + close(fd) + open(newunit=fd, file="otabs.txt", form="formatted") + read(fd,"(a)") line + close(fd, status='delete') + if (line .ne. "1234 67890 ") stop 10 +end program tabs diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 80b60dfeb9f..99ef96a9e7c 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -2072,11 +2072,11 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin dtp->u.p.skips = dtp->u.p.pending_spaces = 0; } - bytes_used = dtp->u.p.current_unit->recl - - dtp->u.p.current_unit->bytes_left; - if (is_stream_io(dtp)) - bytes_used = 0; + bytes_used = dtp->u.p.current_unit->fbuf->act; + else + bytes_used = dtp->u.p.current_unit->recl + - dtp->u.p.current_unit->bytes_left; switch (t) { @@ -2452,7 +2452,11 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin p = ((char *) p) + size; } - pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left; + if (is_stream_io(dtp)) + pos = dtp->u.p.current_unit->fbuf->act; + else + pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left; + dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos; }
[patch, fortran] Bug 105847 - namelist-object-name can be a renamed host associated entity
Pushed as simple and obvious. Regards, Jerry commit 8221201cc59870579b9dc451b173f94b8d8b0993 (HEAD -> master, origin/master, origin/HEAD) Author: Steve Kargl Date: Wed Feb 14 14:40:16 2024 -0800 Fortran: namelist-object-name renaming. PR fortran/105847 gcc/fortran/ChangeLog: * trans-io.cc (transfer_namelist_element): When building the namelist object name, if the use rename attribute is set, use the local name specified in the use statement. gcc/testsuite/ChangeLog: * gfortran.dg/pr105847.f90: New test.
Re: [PATCH] Fortran: deferred length of character variables shall not get lost [PR113911]
On 2/16/24 1:40 PM, Harald Anlauf wrote: Dear all, this patch fixes a regression which was a side-effect of r14-8947, losing the length of a deferred-length character variable when passed as a dummy. The new testcase provides a workout for deferred length to improve coverage in the testsuite. Another temporarily disabled test was re-enabled. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Yes OK for mainline. Thanks, Jerry
[patch, libgfortran] PR107068 Run-time error when reading logical arrays with a namelist
The attached patch fixes this one. Se the ChangeLog below for explanation. OK for trunk? I think simple enough to backport to 13 as well. Regards, Jerry Author: Jerry DeLisle Date: Fri Feb 16 17:06:37 2024 -0800 libgfortran: Fix namelist read. PR libgfortran/107068 libgfortran/ChangeLog: * io/list_read.c (read_logical): When looking for a possible variable name, check for left paren, indicating a possible array reference. gcc/testsuite/ChangeLog: * gfortran.dg/pr107068.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr107068.f90 b/gcc/testsuite/gfortran.dg/pr107068.f90 new file mode 100644 index 000..c5ea0c1d244 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr107068.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +program test + implicit none + integer :: error + logical, dimension(3,3) :: flc,flp + namelist/inputdata/flc, flp + + flc = .false. + flp = .false. + + open(10, file="inputfile") + write(10,*) "&INPUTDATA" + write(10,*) " FLC = T, " + write(10,*) " FLP(1,2) = T," + write(10,*) "/" + rewind(10) + !write(*, nml=inputdata) + !open(10,file="inputfile") + read(10,inputdata,iostat=error) + close(10, status='delete') + if (error /= 0) stop 20 +end program test diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index f8ca64422de..0b7884fdda7 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -888,6 +888,14 @@ read_logical (st_parameter_dt *dtp, int length) for(i = 0; i < 63; i++) { c = next_char (dtp); + if (c == '(') + { + l_push_char (dtp, c); + dtp->u.p.nml_read_error = 1; + dtp->u.p.line_buffer_enabled = 1; + dtp->u.p.line_buffer_pos = 0; + return; + } if (is_separator(c)) { /* All done if this is not a namelist read. */
[patch, libgfortran] Bug 105473 - semicolon allowed when list-directed read integer with decimal='point'
Hello, I posted the attached patch in bugzilla some time ago. This includes a new test case. The patch adds additional checks in key places to catch eroneous use of semicolons Regression tested on x86_64, OK for trunk and later backport to 13? Jerrydiff --git a/gcc/testsuite/gfortran.dg/pr105473.f90 b/gcc/testsuite/gfortran.dg/pr105473.f90 new file mode 100644 index 000..b309217540d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr105473.f90 @@ -0,0 +1,46 @@ +! { dg-do run } +! PR libgfortran/105473 + implicit none + integer n,m,ios + real r + complex z + character(40):: testinput + n = 999; m = 777; r=1.2345 + z = cmplx(0.0,0.0) + +! Check that semi-colon is not allowed as separator with decimal=point. + ios=0 + testinput = '1;17;3.14159' + read(testinput,*,decimal='point',iostat=ios) n, m, r + if (ios /= 5010) print *, "stop 1" + +! Check that comma is not allowed as a separator with decimal=comma. + ios=0 + testinput = '1,17,3,14159' + read(testinput,*,decimal='comma',iostat=ios) n, m, r + if (ios /= 5010) print *, "stop 2" + +! Check a good read. + ios=99 + testinput = '1;17;3,14159' + read(testinput,*,decimal='comma',iostat=ios) n, m, r + if (ios /= 0) print *, "stop 3" + +! Check that comma is not allowed as a separator with decimal=comma. + ios=99; z = cmplx(0.0,0.0) + testinput = '1,17, (3,14159, 1,7182)' + read(testinput,*,decimal='comma', iostat=ios) n, m, z + if (ios /= 5010) stop 4 + +! Check that semi-colon is not allowed as separator with decimal=point. + ios=99; z = cmplx(0.0,0.0) + testinput = '1,17; (3.14159; 1.7182)' + read(testinput,*,decimal='point', iostat=ios) n, m, z + if (ios /= 5010) stop 5 + +! Check a good read. + ios=99;z = cmplx(0.0,0.0) + testinput = '1;17; (3,14159; 1,7182)' + read(testinput,*,decimal='comma', iostat=ios) n, m, z + if (ios /= 0) stop 6 +end program diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 0b7884fdda7..d2316ad6fe2 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -53,7 +53,6 @@ typedef unsigned char uchar; #define CASE_SEPARATORS /* Fall through. */ \ case ' ': case ',': case '/': case '\n': \ case '\t': case '\r': case ';' - /* This macro assumes that we're operating on a variable. */ #define is_separator(c) (c == '/' || c == ',' || c == '\n' || c == ' ' \ @@ -475,11 +474,23 @@ eat_separator (st_parameter_dt *dtp) case ',': if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) { + generate_error (&dtp->common, LIBERROR_READ_VALUE, + "Comma not allowed as separator with DECIMAL='comma'"); unget_char (dtp, c); break; } - /* Fall through. */ + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + break; + case ';': + if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT) + { + generate_error (&dtp->common, LIBERROR_READ_VALUE, + "Semicolon not allowed as separator with DECIMAL='point'"); + unget_char (dtp, c); + break; + } dtp->u.p.comma_flag = 1; eat_spaces (dtp); break; @@ -1326,8 +1337,13 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length) { if ((c = next_char (dtp)) == EOF) goto bad; - if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) - c = '.'; + if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) + { + if (c == '.') + goto bad; + if (c == ',') + c = '.'; + } switch (c) { CASE_DIGITS: @@ -1636,8 +1652,18 @@ read_real (st_parameter_dt *dtp, void *dest, int length) seen_dp = 0; c = next_char (dtp); - if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) -c = '.'; + if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) +{ + if (c == '.') + goto bad_real; + if (c == ',') + c = '.'; +} + if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT) +{ + if (c == ';') + goto bad_real; +} switch (c) { CASE_DIGITS: @@ -1677,8 +1703,13 @@ read_real (st_parameter_dt *dtp, void *dest, int length) for (;;) { c = next_char (dtp); - if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) - c = '.'; + if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) + { + if (c == '.') + goto bad_real; + if (c == ',') + c = '.'; + } switch (c) { CASE_DIGITS: @@ -1718,7 +1749,7 @@ read_real (st_parameter_dt *dtp, void *dest, int length) CASE_SEPARATORS: case EOF: - if (c != '\n' && c != ',' && c != '\r' && c != ';') + if (c != '\n' && c != ',' && c != ';' && c != '\r') unget_char (dtp, c); goto done; diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index e2d2f8be806..7a9e341d7d8 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -1062,8 +1062,17 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) case ',': if (dtp->u.p.current_unit->decimal_status != DECIMAL_C
Re: [PATCH] Fix fortran/PR114024
On 2/21/24 10:30 AM, Steve Kargl wrote: I have attached a patch to PR114024, see https://gcc.gnu.org/pipermail/gcc-bugs/2024-February/854651.html The patch contains a new testcase and passes regression testing on x86_64-*-freebsd. Could someone castr an eye over the patch and commit it? Hi Steve, I looked it over and looks reasonable. I will try to apply it next few days and test here. If OK, I will commit. Jerry
Re: [PATCH] Fix fortran/PR114024
On 2/21/24 12:28 PM, Harald Anlauf wrote: On 2/21/24 20:41, Jerry D wrote: On 2/21/24 10:30 AM, Steve Kargl wrote: I have attached a patch to PR114024, see https://gcc.gnu.org/pipermail/gcc-bugs/2024-February/854651.html The patch contains a new testcase and passes regression testing on x86_64-*-freebsd. Could someone castr an eye over the patch and commit it? Hi Steve, I looked it over and looks reasonable. I will try to apply it next few days and test here. If OK, I will commit. Jerry Actually the patch has two issues: - a minor one: a new front-end memleak which can be avoided by using either gfc_replace_expr (see its other uses) Hint: try valgrind on f951 Yes, I am learning to do that. - it still fails on the following code, because the traversal of the refs is incomplete / wrong: program foo implicit none complex :: cmp(3) real, pointer :: pp(:) class(*), allocatable :: uu(:) type t real :: re real :: im end type t type u type(t) :: tt(3) end type u type(u) :: cc cmp = (3.45,6.78) cc% tt% re = cmp% re cc% tt% im = cmp% im allocate (pp, source = cc% tt% im) ! ICE print *, pp allocate (uu, source = cc% tt% im) ! ICE end This still crashes for me for the indicated cases. Harald Good catch. I will hold off until that is figured out. Jerry
[patch, libgfortran] PR105456 Child I/O does not propage iostat
Hi all, The attached fix adds a check for an error condition from a UDDTIO procedure in the case where there is no actual underlying error, but the user defines an error by setting the iostat variable manually before returning to the parent READ. I did not address the case of a formatted WRITE or unformatted READ/WRITE until I get some feedback on the approach. If this approach is OK I would like to commit and then do a separate patch for the cases I just mentioned. Feedback appreciated. Regression tested on x86_64. OK for trunk? Jerry Author: Jerry DeLisle Date: Thu Feb 22 10:48:39 2024 -0800 libgfortran: Propagate user defined iostat and iomsg. PR libfortran/105456 libgfortran/ChangeLog: * io/list_read.c (list_formatted_read_scalar): Add checks for the case where a user defines their own error codes and error messages and generate the runtime error. gcc/testsuite/ChangeLog: * gfortran.dg/pr105456.f90: New test.diff --git a/gcc/testsuite/gfortran.dg/pr105456.f90 b/gcc/testsuite/gfortran.dg/pr105456.f90 new file mode 100644 index 000..411873f4aed --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr105456.f90 @@ -0,0 +1,41 @@ +! { dg-do run } +! { dg-shouldfail "The users message" } +module sk1 + implicit none + type char + character :: ch + end type char + interface read (formatted) + module procedure read_formatted + end interface read (formatted) +contains + subroutine read_formatted (dtv, unit, iotype, vlist, piostat, piomsg) +class (char), intent(inout) :: dtv +integer, intent(in) :: unit +character (len=*), intent(in) :: iotype +integer, intent(in) :: vlist(:) +integer, intent(out) :: piostat +character (len=*), intent(inout) :: piomsg +character :: ch +read (unit,fmt='(A1)', advance="no", iostat=piostat, iomsg=piomsg) ch +piostat = 42 +piomsg="The users message" +dtv%ch = ch + end subroutine read_formatted +end module sk1 + +program skip1 + use sk1 + implicit none + integer :: myerror = 0 + character(64) :: mymessage = "" + type (char) :: x + open (10,status="scratch") + write (10,'(A)') '', 'a' + rewind (10) + read (10,*) x + print *, myerror, mymessage + write (*,'(10(A))') "Read: '",x%ch,"'" +end program skip1 +! { dg-output ".*(unit = 10, file = .*)" } +! { dg-output "Fortran runtime error: The users message" } diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 3d29cb64813..ee3ab713519 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2138,6 +2138,7 @@ static int list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, int kind, size_t size) { + char message[MSGLEN]; gfc_char4_t *q, *r; size_t m; int c; @@ -2247,7 +2248,7 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT) ? dtp->common.iostat : &noiostat); - /* Set iomsge, intent(inout). */ + /* Set iomsg, intent(inout). */ if (dtp->common.flags & IOPARM_HAS_IOMSG) { child_iomsg = dtp->common.iomsg; @@ -2266,6 +2267,25 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, iotype_len, child_iomsg_len); dtp->u.p.child_saved_iostat = *child_iostat; dtp->u.p.current_unit->child_dtio--; + + + if ((dtp->u.p.child_saved_iostat != 0) && + !(dtp->common.flags & IOPARM_HAS_IOMSG) && + !(dtp->common.flags & IOPARM_HAS_IOSTAT)) + { + /* Trim trailing spaces from the message. */ + for(int i = IOMSG_LEN - 1; i > 0; i--) + if (!isspace(child_iomsg[i])) + { + /* Add two to get back to the end of child_iomsg. */ + child_iomsg_len = i+2; + break; + } + free_line (dtp); + snprintf (message, child_iomsg_len, child_iomsg); + generate_error (&dtp->common, dtp->u.p.child_saved_iostat, + message); + } } break; default:
Re: [patch, libgfortran] PR105456 Child I/O does not propage iostat
On 2/25/24 12:34 PM, Harald Anlauf wrote: Hi Jerry, On 2/22/24 20:11, Jerry D wrote: Hi all, The attached fix adds a check for an error condition from a UDDTIO procedure in the case where there is no actual underlying error, but the user defines an error by setting the iostat variable manually before returning to the parent READ. the libgfortran fix LGTM. Regarding the testcase code, the following looks like you left some debugging code in it: + rewind (10) + read (10,*) x + print *, myerror, mymessage + write (*,'(10(A))') "Read: '",x%ch,"'" --- snip --- I cleaned up the test case. Thanks for review. The master branch has been updated by Jerry DeLisle : https://gcc.gnu.org/g:3f58f96a4e8255e222953f9856bcd6c25f7b33cd Regards, Jerry
Re: [PATCH] Fortran: do not evaluate polymorphic functions twice in assignment [PR114012]
On 2/25/24 12:26 PM, Harald Anlauf wrote: Dear all, the attached simple patch fixes an issue where we evaluated polymorphic functions twice in assignments: once for the _data component, and once for the _vptr. Using save_expr prevents the double evaluation. Regtested on x86_64-pc-linux-gnu. OK for mainline? And a backport to 13-branch after some delay? Thanks, Harald Yes, simple enough. OK. Thanks, Jerry
Re: [PATCH] Fortran testsuite: fix invalid Fortran in testcase
On 2/27/24 1:00 PM, Harald Anlauf wrote: Dear all, the attached patch fixes invalid Fortran in testcase gfortran.dg/pr101026.f, which might prohibit progress in fixing pr111781. (Note that the testcase was for a tree-optimizer issue, not the Fortran frontend.) OK for mainline? Will commit within 24h unless there are comments. Thanks, Harald OK, simple.
[patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
The attached patch adds the error checks similar to the first patch previously committed. I noticed a redundancy in some defines MSGLEN and IOMSG_LEN so I consolidated this to one define in io.h. This is just cleanup stuff. I have added test cases for each of the places where UDTIO is done in the library. Regressions tested on x86_64. OK for trunk? Regards, Jerry commit 640991bd6b83df4197b2eaec63d1e0e695e48b75 Author: Jerry DeLisle Date: Wed Feb 28 20:51:06 2024 -0800 Fortran: Add user defined error messages for UDTIO. The defines IOMSG_LEN and MSGLEN were redundant so these are combined into IOMSG_LEN as defined in io.h. The remainder of the patch adds checks for when a user defined derived type IO procedure sets the IOSTAT or IOMSG variables independent of the librrary defined I/O messages. PR libfortran/105456 libgfortran/ChangeLog: * io/io.h (IOMSG_LEN): Moved to here. * io/list_read.c (MSGLEN): Removed MSGLEN. (convert_integer): Changed MSGLEN to IOMSG_LEN. (parse_repeat): Likewise. (read_logical): Likewise. (read_integer): Likewise. (read_character): Likewise. (parse_real): Likewise. (read_complex): Likewise. (read_real): Likewise. (check_type): Likewise. (list_formatted_read_scalar): Adjust to IOMSG_LEN. (nml_read_obj): Add user defined error message. * io/transfer.c (unformatted_read): Add user defined error message. (unformatted_write): Add user defined error message. (formatted_transfer_scalar_read): Add user defined error message. (formatted_transfer_scalar_write): Add user defined error message. * io/write.c (list_formatted_write_scalar): Add user defined error message. (nml_write_obj): Add user defined error message. gcc/testsuite/ChangeLog: * gfortran.dg/pr105456-nmlr.f90: New test. * gfortran.dg/pr105456-nmlw.f90: New test. * gfortran.dg/pr105456-ruf.f90: New test. * gfortran.dg/pr105456-wf.f90: New test. * gfortran.dg/pr105456-wuf.f90: New test.diff --git a/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 b/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 new file mode 100644 index 000..5ce5d082133 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr105456-nmlr.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +! { dg-shouldfail "The users message" } +module m + implicit none + type :: t +character :: c +integer :: k + contains +procedure :: write_formatted +generic :: write(formatted) => write_formatted +procedure :: read_formatted +generic :: read(formatted) => read_formatted + end type +contains + subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg) +class(t), intent(in) :: dtv +integer, intent(in) :: unit +character(*), intent(in) :: iotype +integer, intent(in) :: v_list(:) +integer, intent(out) :: iostat +character(*), intent(inout) :: iomsg +if (iotype.eq."NAMELIST") then + write (unit, '(a1,a1,i3)') dtv%c,',', dtv%k +else + write (unit,*) dtv%c, dtv%k +end if + end subroutine + subroutine read_formatted(dtv, unit, iotype, v_list, iostat, iomsg) +class(t), intent(inout) :: dtv +integer, intent(in) :: unit +character(*), intent(in) :: iotype +integer, intent(in) :: v_list(:) +integer, intent(out) :: iostat +character(*), intent(inout) :: iomsg +character :: comma +if (iotype.eq."NAMELIST") then + read (unit, '(a1,a1,i3)') dtv%c, comma, dtv%k +else + read (unit,*) dtv%c, comma, dtv%k +endif +iostat = 42 +iomsg = "The users message" +if (comma /= ',') STOP 1 + end subroutine +end module + +program p + use m + implicit none + character(len=50) :: buffer + type(t) :: x + namelist /nml/ x + x = t('a', 5) + write (buffer, nml) + if (buffer.ne.' &NML X=a, 5 /') STOP 1 + x = t('x', 0) + read (buffer, nml) + if (x%c.ne.'a'.or. x%k.ne.5) STOP 2 +end +! { dg-output "Fortran runtime error: The users message" } diff --git a/gcc/testsuite/gfortran.dg/pr105456-nmlw.f90 b/gcc/testsuite/gfortran.dg/pr105456-nmlw.f90 new file mode 100644 index 000..2c496e611f4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr105456-nmlw.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +! { dg-shouldfail "The users message" } +module m + implicit none + type :: t +character :: c +integer :: k + contains +procedure :: write_formatted +generic :: write(formatted) => write_formatted +procedure :: read_formatted +generic :: read(formatted) => read_formatted + end type +contains + subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg) +class(t), intent(in) :: dtv +integer, intent(in) :: unit +character(*), intent(in) :: iotype +integer, intent(in) :: v_list(
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 2/29/24 1:47 AM, Bernhard Reutner-Fischer wrote: On Wed, 28 Feb 2024 21:29:06 -0800 Jerry D wrote: The attached patch adds the error checks similar to the first patch previously committed. I noticed a redundancy in some defines MSGLEN and IOMSG_LEN so I consolidated this to one define in io.h. This is just cleanup stuff. I have added test cases for each of the places where UDTIO is done in the library. Regressions tested on x86_64. OK for trunk? I think the commit hooks will complain about several missing spaces before open brace; See contrib/check_GNU_style.py /tmp/pr105456-3.diff I was given the OK from git gcc-verify. Regardless if hooks fail I just fix and try again. Would it make sense to introduce and use an internal helper like trim()? Or would it be possible to trim the message in generate_error_common()? I was debating this and what would be the best approach. I was not sure where to put it. I like the idea of doing in the generate_error_common. I will try that and see how it plays. And, just for my own education, the length limitation of iomsg to 255 chars is not backed by the standard AFAICS, right? It's just our STRERR_MAXSZ? Yes, its what we have had for a long lone time. Once you throw an error things get very processor dependent. I found MSGLEN set to 100 and IOMSG_len to 256. Nothing magic about it. I appreciate the comments. --- snip --- Jerry -
Re: PR82943 - Suggested patch to fix
On 1/20/24 10:46 AM, Alexander Westbrooks wrote: Hello and Happy New Year! I wanted to follow up on this patch I made to address PR82943 for GFortran. Has anyone had a chance to review it? Thanks, Alexander Westbrooks Inserting myself in here just a little bit. I will apply and test today if I can. Paul is unavailable for a few weeks. Harald can chime in. Do you have commit rights for gcc? Your efforts are appreciated. Regards, Jerry
Re: PR82943 - Suggested patch to fix
On 1/20/24 11:08 AM, Jerry D wrote: On 1/20/24 10:46 AM, Alexander Westbrooks wrote: Hello and Happy New Year! I wanted to follow up on this patch I made to address PR82943 for GFortran. Has anyone had a chance to review it? Thanks, Alexander Westbrooks Inserting myself in here just a little bit. I will apply and test today if I can. Paul is unavailable for a few weeks. Harald can chime in. Do you have commit rights for gcc? Your efforts are appreciated. Regards, Jerry I did send you an invite to our Mattermost workspace. I did apply your patch. Some comments. The ChangeLog files are auto generated so do not get manually changed with a patch. The push process to the gcc git repository will generate those from the git commit log. If the git commit log is not formatted correctly the push will be rejected. The patch attempts to create a PDT_33.f03 test case. There is one already there so probably rename that one. In resolve.cc There was a compile error that looked like an extra '&&' in the conditional. I deleted that and all compiled ok and all regression tested OK, including your new test cases and the existing PDT_33.f03 case. I did not try your new test case yet for PDT_33. So next steps are walk you through using the git scripts to make commits with the logs formatted correctly. (assuming no one else chimes in with any other comment about code changes themselves.. Regards, Jerry
Re: PR82943 - Suggested patch to fix
On 1/20/24 12:08 PM, Harald Anlauf wrote: Am 20.01.24 um 20:08 schrieb Jerry D: On 1/20/24 10:46 AM, Alexander Westbrooks wrote: Hello and Happy New Year! I wanted to follow up on this patch I made to address PR82943 for GFortran. Has anyone had a chance to review it? Thanks, Alexander Westbrooks Inserting myself in here just a little bit. I will apply and test today if I can. Paul is unavailable for a few weeks. Harald can chime in. Do you have commit rights for gcc? I am not aware of Alex having a copyright assignment on file, or a DCO certificate, and the patch is not signed off. But I might be wrong. --- snip --- I do not mind committing this but need clarifications regarding the copyright (copyleft?) rules in this case. In the past we have allowed small contributions like this. This may be a little more than minor. Regardless it appears to do the job! Jerry
[patch, libgfortran] PR111022 ES0.0E0 format gave ES0.dE0 output with d too high.
The attached patch attempts to fix the handling of the EN0.0E0 and ES0.0E0 formatting by correctly calculating the number of digits needed for the exponents and building those exponents into the float string. My editor judiciously deleted trailing blank spaces in a number of places. I apologize for the clutter, but we might as well get rid of it now. Two existing test cases needed to be adjusted and I am adding one new test case to capture the changes in our testsuite. Regression tested on X86_64. OK for trunk? Do we need to backport this? Regards, Jerry Author: Jerry DeLisle Date: Tue Jan 30 09:45:49 2024 -0800 libgfortran: EN0.0E0 and ES0.0E0 format editing. PR libgfortran/111022 F2018 and F2023 standards added zero width exponents. This required additional special handing in the process of building formatted floating point strings. libgfortran/ChangeLog: * io/write.c (select_buffer): Whitespace. (write_real): Whitespace. (write_real_w0): Adjust logic for d==0. * io/write_float.def (determine_precision): Whitespace. (build_float_string): Calculate the width of the E0 exponents. (build_infnan_string): Whitespace. (CALCULATE_EXP): Whitespace (quadmath_snprintf): Whitespace. (determine_en_precision): Whitespace. gcc/testsuite/ChangeLog: * gfortran.dg/pr96436_4.f90: Changed for ES0 and EN0. * gfortran.dg/pr96436_5.f90: Changed for ES0 and EN0. * gfortran.dg/pr111022.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr111022.f90 b/gcc/testsuite/gfortran.dg/pr111022.f90 new file mode 100644 index 000..d7e8edf2d19 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr111022.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +program case2 + character(20) :: buffer + write(buffer,"(EN0.3E0)") .6660_4 + if (buffer.ne."666.000E-3") stop 1 + write(buffer,"(EN0.3E0)") 6.660_4 + if (buffer.ne."6.660E+0") stop 2 + write(buffer,"(EN0.3E0)") 66.60_4 + if (buffer.ne."66.600E+0") stop 3 + write(buffer,"(EN0.3E0)") 666.0_4 + if (buffer.ne."666.000E+0") stop 4 + write(buffer,"(EN0.3E0)") 6660.0_4 + if (buffer.ne."6.660E+3") stop 5 + write(buffer,"(EN0.3E0)") 66600.0_4 + if (buffer.ne."66.600E+3") stop 6 + + write(buffer,"(EN0.0E0)") 666.0_4 + if (buffer.ne."666.E+0") stop 7 + write(buffer,"(EN0.0E1)") 666.0_4 + if (buffer.ne."666.E+0") stop 8 + write(buffer,"(EN0.0E2)") 666.0_4 + if (buffer.ne."666.E+00") stop 9 + write(buffer,"(EN0.0E3)") 666.0_4 + if (buffer.ne."666.E+000") stop 10 + write(buffer,"(EN0.0E4)") 666.0_4 + if (buffer.ne."666.E+") stop 11 + write(buffer,"(EN0.0E5)") 666.0_4 + if (buffer.ne."666.E+0") stop 12 + write(buffer,"(EN0.0E6)") 666.0_4 + if (buffer.ne."666.E+00") stop 13 + + write(buffer,"(ES0.3E0)") .6660_4 + if (buffer.ne."6.660E-1") stop 14 + write(buffer,"(ES0.3E0)") 6.660_4 + if (buffer.ne."6.660E+0") stop 15 + write(buffer,"(ES0.3E0)") 66.60_4 + if (buffer.ne."6.660E+1") stop 16 + write(buffer,"(ES0.3E0)") 666.0_4 + if (buffer.ne."6.660E+2") stop 17 + write(buffer,"(ES0.3E0)") 6660.0_4 + if (buffer.ne."6.660E+3") stop 18 + write(buffer,"(ES0.3E0)") 66600.0_4 + if (buffer.ne."6.660E+4") stop 19 + + write(buffer,"(ES0.0E0)") 666.0_4 + if (buffer.ne."7.E+2") stop 20 + write(buffer,"(ES0.0E1)") 666.0_4 + if (buffer.ne."7.E+2") stop 21 + write(buffer,"(ES0.0E2)") 666.0_4 + if (buffer.ne."7.E+02") stop 22 + write(buffer,"(ES0.0E3)") 666.0_4 + if (buffer.ne."7.E+002") stop 23 + write(buffer,"(ES0.0E4)") 666.0_4 + if (buffer.ne."7.E+0002") stop 24 + write(buffer,"(ES0.0E5)") 666.0_4 + if (buffer.ne."7.E+2") stop 25 + write(buffer,"(ES0.0E6)") 666.0_4 + if (buffer.ne."7.E+02") stop 26 + +end program case2 diff --git a/gcc/testsuite/gfortran.dg/pr96436_4.f90 b/gcc/testsuite/gfortran.dg/pr96436_4.f90 index 335ce5fb009..7d2cfef0ef8 100644 --- a/gcc/testsuite/gfortran.dg/pr96436_4.f90 +++ b/gcc/testsuite/gfortran.dg/pr96436_4.f90 @@ -17,9 +17,9 @@ write(buffer,fmt) ">", 3.0, "<" if (buffer.ne.">0.30E+1<") stop 4 fmt = "(1a1,en0.2,1a1)" write(buffer,fmt) ">", 3.0, "<" -if (buffer.ne.">3.00<") stop 5 +if (buffer.ne.">3.00E+0<") stop 5 fmt = "(1a1,es0.2,1a1)" write(buffer,fmt) ">", 3.0, "<" -if (buffer.ne.">3.00<") stop 6 +if (buffer.ne.">3.00E+0<") stop 6 end diff --git a/gcc/testsuite/gfortran.dg/pr96436_5.f90 b/gcc/testsuite/gfortran.dg/pr96436_5.f90 index a45df8963c8..3870d988f97 100644 --- a/gcc/testsuite/gfortran.dg/pr96436_5.f90 +++ b/gcc/testsuite/gfortran.dg/pr96436_5.f90 @@ -17,9 +17,9 @@ write(buffer,fmt) ">", 3.0, "<" if (buffer.ne.">0.30E+1<") stop 4 fmt = "(1a1,en0.2,1a1)" write(buffer,fmt) ">", 3.0, "<" -if (buffer.ne.">3.00<") stop 5 +if (buffer.ne.">3.00E+0<") stop 5 fmt = "(1a1,es0.2,1a1)" write(buffer,fmt) ">", 3.0, "<" -if (buffer.ne.">3.00<") stop 6 +if (buffer.ne.">3.00E+0<") stop 6 end diff --git a/l
[patch, fortran, committed] PR112873 F2023 degree trig functions
The following has been committed per discussion in the subject PR. commit 95b70545331764c85079a1d0e1e19b605bda1456 (HEAD -> master, origin/master, origin/HEAD) Author: Jerry DeLisle Date: Wed Dec 13 19:04:50 2023 -0800 fortran: Add degree based trig functions for F2023 PR fortran/112873 gcc/fortran/ChangeLog: * gfortran.texi: Update to reflect the changes. * intrinsic.cc (add_functions): Update the standard that the various degree trigonometric functions have been described in. (gfc_check_intrinsic_standard): Add an error string for F2023. * intrinsic.texi: Update accordingly. Thanks to Steve for the changes checked by Harald and myself. I know there is a way to do a co-Author on a git commit. Will try to do that next time when it applies. Jerry
[libgfortran, patch] PR113223 NAMELIST internal write missing leading blank character
Committed as simple and obvious. Initial patch thanks to Steve. When using git gcc-commit-mklog how does one add in the coauthor? The master branch has been updated by Jerry DeLisle : https://gcc.gnu.org/g:add995ec117d756e61d207041cd32f937c1a1cd9 commit r14-6986-gadd995ec117d756e61d207041cd32f937c1a1cd9 Author: Jerry DeLisle Date: Sun Jan 7 10:22:19 2024 -0800 libgfortran: Emit a space at beginning of internal unit NML. PR libgfortran/113223 libgfortran/ChangeLog: * io/write.c (namelist_write): If internal_unit precede with space. gcc/testsuite/ChangeLog: * gfortran.dg/dtio_25.f90: Update. * gfortran.dg/namelist_57.f90: Update. * gfortran.dg/namelist_65.f90: Update.
Re: {Patch, fortran] PR112834 - Class array function selector causes chain of syntax and other spurious errors
On 12/6/23 8:09 AM, Paul Richard Thomas wrote: Dear All, This patch was rescued from my ill-fated and long winded attempt to provide a fix-up for function selector references, where the function is parsed after the procedure containing the associate/select type construct (PRs 89645 and 99065). The fix-ups broke down completely once these constructs were enclosed by another associate construct, where the selector is a derived type or class function. My inclination now is to introduce two pass parsing for contained procedures. Returning to PR112834, the patch is simple enough and is well described by the change logs. PR111853 was fixed as a side effect of the bigger patch. Steve Kargl had also posted the same fix on the PR. Regression tests - OK for trunk and 13-branch? Paul Hi Paul, I am taking a crack at this. It looks reasonable to me. Certainly OK for trunk, and then, if no fallout, 13 at your discretion. Regards, Jerry
Re: [PATCH] Fortran: fix ALLOCATE with SOURCE=, zero-length character [PR83865]
On 6/3/24 1:12 PM, Harald Anlauf wrote: Dear all, the attached simple patch fixes an ICE for ALLOCATE with SOURCE= of a deferred-length character array with source-expression being an array of character with length zero. The reason was that the array descriptor of the source-expression was discarded in the special case of length 0. Solution: restrict special case to rank 0. Regtested on x86_64-pc-linux-gnu. OK for mainline? The offending code was introduced during 7-development, so it is technically a regression. I would therefore like to backport after waiting for a week or two. Thanks, Harald OK and thanks for patch. Jerry
Re: [Ping x 3, Fortran, Patch, coarray, PR84246, v2] Fix for [Coarray] ICE in conv_caf_send, at fortran/trans-intrinsic.c:1950
On 8/19/24 4:43 AM, Andre Vehreschild wrote: Hi all, another ping on this patch. Regtests ok on x86_64-pc-linux-gnu on updated master. Ok for mainline? Regards, Andre Looks OK to go ahead Andre. Thanks, Jerry On Fri, 9 Aug 2024 16:29:08 +0200 Andre Vehreschild wrote: Ping! On Wed, 17 Jul 2024 15:15:51 +0200 Andre Vehreschild wrote: Hi all, attached patch fixes an ICE in coarray code, where the coarray expression already was a pointer, which confused the compiler. Furthermore have I removed a rewrite to a caf_send late in the trans-phase. This is now done in the resolve stage to have only a single place for these rewriting actions. Regtests ok on x86_64-pc-linux-gnu / Fedora 39. Ok for mainline? Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de -- Andre Vehreschild * Email: vehre ad gmx dot de
Re: [Ping x2 , Fortran, Patch, PR77518, (coarray), v4] Fix ICE in sizeof(coarray)
On 8/20/24 5:35 AM, Andre Vehreschild wrote: Hi all, pinging this patch. Regtests ok on x86_64-pc-linux-gnu / Fedora 39. Ok for mainline? Regards, Andre Your approach looks reasonable so I think OK to push. Thanks, Jerry
Re: [pushed] readings: Drop FORTRAN 77 test suite at itl.nist.gov
On 6/18/24 10:20 AM, Steve Kargl wrote: On Tue, Jun 18, 2024 at 09:13:23AM +0200, Gerald Pfeifer wrote: The original subsite has disappeared and we couldn't find it elsewhere. https://github.com/gklimowicz/FCVS gklimowicz is a flang developer and member of J3. FWIW my copy of the tests still pass: --- snip --- FM921 compiles and runs OK ***FM922*** FM922 compiles and runs OK ***FM923*** FM923 compiles and runs OK The logfile is nist.log 0 compilation errors or warnings 0 load and link errors 0 runtime errors 192 completely successful
[patch, libgfortran] PR105361 Incorrect end-of-file condition for derived-type I/O
Hi all, The attached patch fixes this by avoiding looking for and avoiding the EOF condition in the parent READ after returning from the child IO process. I could not think of a simple test case yet since the problem occurred only when redirecting the input to the test program via a pipe. If I have some more time today I will try to come up with something. OK for mainline? Jerry commit e6fa9d84cf126630c9ea744aabec6d7715087310 (HEAD -> master) Author: Jerry DeLisle Date: Sun Jul 21 19:19:00 2024 -0700 Fortran: Suppress wrong End Of File error with user defined IO. libgfortran/ChangeLog: PR libfortran/105361 * io/list_read.c (finish_list_read): Add a condition check for a user defined derived type IO operation to avoid calling the EOF error. diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 5bbbef26c26..96b2efe854f 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2431,7 +2431,8 @@ finish_list_read (st_parameter_dt *dtp) /* Set the next_char and push_char worker functions. */ set_workers (dtp); - if (likely (dtp->u.p.child_saved_iostat == LIBERROR_OK)) + if (likely (dtp->u.p.child_saved_iostat == LIBERROR_OK) + && ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)) { c = next_char (dtp); if (c == EOF)
ping Re: [patch, libgfortran] PR105361 Incorrect end-of-file condition for derived-type I/O
On 7/22/24 8:13 AM, Jerry D wrote: Hi all, The attached patch fixes this by avoiding looking for and avoiding the EOF condition in the parent READ after returning from the child IO process. I could not think of a simple test case yet since the problem occurred only when redirecting the input to the test program via a pipe. If I have some more time today I will try to come up with something. OK for mainline? Jerry commit e6fa9d84cf126630c9ea744aabec6d7715087310 (HEAD -> master) Author: Jerry DeLisle Date: Sun Jul 21 19:19:00 2024 -0700 Fortran: Suppress wrong End Of File error with user defined IO. libgfortran/ChangeLog: PR libfortran/105361 * io/list_read.c (finish_list_read): Add a condition check for a user defined derived type IO operation to avoid calling the EOF error. I failed to mention that this patch regression tests OK on x86_64. I also developed the attached test case. This does reproduce the error. I will update the log entry to reflect this test case. OK for mainline?! { dg-do run } module x implicit none type foo real :: r end type foo interface read(formatted) module procedure read_formatted end interface read(formatted) contains subroutine read_formatted (dtv, unit, iotype, vlist, iostat, iomsg) class (foo), intent(inout) :: dtv integer, intent(in) :: unit character (len=*), intent(in) :: iotype integer, intent(in) :: vlist(:) integer, intent(out) :: iostat character (len=*), intent(inout) :: iomsg read (unit,*,iostat=iostat,iomsg=iomsg) dtv%r !print *,dtv%r end subroutine read_formatted end module x program main use x implicit none type(foo) :: a, b real :: c, d open(10, access="stream") write(10) "1 2" ! // NEW_LINE('A') close(10) open(10) read(10,*) c, d if ((c /= 1.0) .or. (d /= 2.0)) stop 1 rewind(10) !print *, c,d read (10,*) a, b close(10, status="delete") if ((a%r /= 1.0) .or. (b%r /= 2.0)) stop 2 !print *, a,b end program main
[Patch, libgfortran] PR105361 Followup fix to test case
I plan to push this soon to hopefully fix some test breakage on some architetures. It is simple and obvious. I did not get any feedback on this and I do not have access to the machines in question. Regression tested on linux-x86-64. Regards, Jerry commit bc4ee05dc7c60d534ef927ac5e679f67fb99d54b Author: Jerry DeLisle Date: Wed Jul 31 08:58:17 2024 -0700 Fortran: Add newline character to test input. gcc/testsuite/ChangeLog: PR libfortran/105361 * gfortran.dg/pr105361.f90: Add newline character to test input to provide more compliant test. diff --git a/gcc/testsuite/gfortran.dg/pr105361.f90 b/gcc/testsuite/gfortran.dg/pr105361.f90 index e2d3b07caca..62821c2802d 100644 --- a/gcc/testsuite/gfortran.dg/pr105361.f90 +++ b/gcc/testsuite/gfortran.dg/pr105361.f90 @@ -27,7 +27,7 @@ program main type(foo) :: a, b real :: c, d open(10, access="stream") - write(10) "1 2" ! // NEW_LINE('A') + write(10) "1 2" // NEW_LINE('A') close(10) open(10) read(10,*) c, d
[Patch, Fortran] PR104626 ICE in gfc_format_decoder, at fortran/error.cc:1071
Hi all, Doing some catchup here. I plan to commit the following shortly. This is one of Steve's patches posted on bugzilla. I have created a new test case. Regression tested on linux x86-64. git show: commit 4d4549937b789afe4037c2f8f80dfc2285504a1e (HEAD -> master) Author: Steve Kargl Date: Thu Aug 1 21:50:49 2024 -0700 Fortran: Fix ICE on invalid in gfc_format_decoder. PR fortran/104626 gcc/fortran/ChangeLog: * symbol.cc (gfc_add_save): Add checks for SAVE attribute conflicts and duplicate SAVE attribute. gcc/testsuite/ChangeLog: * gfortran.dg/pr104626.f90: New test. diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index a8479b862e3..b5143d9f790 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -1307,9 +1307,8 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, if (s == SAVE_EXPLICIT && gfc_pure (NULL)) { - gfc_error - ("SAVE attribute at %L cannot be specified in a PURE procedure", -where); + gfc_error ("SAVE attribute at %L cannot be specified in a PURE " +"procedure", where); return false; } @@ -1319,10 +1318,15 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name, if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT && (flag_automatic || pedantic)) { - if (!gfc_notify_std (GFC_STD_LEGACY, -"Duplicate SAVE attribute specified at %L", -where)) + if (!where) + { + gfc_error ("Duplicate SAVE attribute specified near %C"); return false; + } + + if (!gfc_notify_std (GFC_STD_LEGACY, "Duplicate SAVE attribute " + "specified at %L", where)) + return false; } attr->save = s; diff --git a/gcc/testsuite/gfortran.dg/pr104626.f90 b/gcc/testsuite/gfortran.dg/pr104626.f90 new file mode 100644 index 000..faff65a8c92 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr104626.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +program p + procedure(g), save :: f ! { dg-error "PROCEDURE attribute conflicts" } + procedure(g), save :: f ! { dg-error "Duplicate SAVE attribute" } +contains + subroutine g + end +end
[Patch, Fortran] Bug 109105 - Error-prone format string building in resolve.cc
Hi all, The attached patch changes all the snprintf calls to regular gfc_error calls to cleanup translation. I introduced a simple macro to facilitate doing the checks that were being done in the bad_op code section. From the description for the call to gfc_extend_expr interfaces are mentioned so I used the CHECK_INTERFACES name for the macro. Regression tested on linux-x86_64. No new test cases. OK for mainline? Backport? Regards, Jerry Author: Jerry DeLisle Date: Tue Aug 6 12:47:30 2024 -0700 Fortran: Eliminate error prone translations. PR fortran/109105 gcc/fortran/ChangeLog: * resolve.cc (CHECK_INTERFACES): New helper macro. (resolve_operator): Replace use of snprintf with gfc_error. diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 503029364c1..eb3085a05ca 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -4137,15 +4137,23 @@ convert_to_numeric (gfc_expr *a, gfc_expr *b) } /* Resolve an operator expression node. This can involve replacing the - operation with a user defined function call. */ + operation with a user defined function call. CHECK_INTERFACES is a + helper macro. */ + +#define CHECK_INTERFACES \ + { \ +match m = gfc_extend_expr (e); \ +if (m == MATCH_YES) \ + return true; \ +if (m == MATCH_ERROR) \ + return false; \ + } static bool resolve_operator (gfc_expr *e) { gfc_expr *op1, *op2; /* One error uses 3 names; additional space for wording (also via gettext). */ - char msg[3*GFC_MAX_SYMBOL_LEN + 1 + 50]; - bool dual_locus_error; bool t = true; /* Reduce stacked parentheses to single pair */ @@ -4195,8 +4203,6 @@ resolve_operator (gfc_expr *e) if (t == false) return false; - dual_locus_error = false; - /* op1 and op2 cannot both be BOZ. */ if (op1 && op1->ts.type == BT_BOZ && op2 && op2->ts.type == BT_BOZ) @@ -4210,9 +4216,9 @@ resolve_operator (gfc_expr *e) if ((op1 && op1->expr_type == EXPR_NULL) || (op2 && op2->expr_type == EXPR_NULL)) { - snprintf (msg, sizeof (msg), - _("Invalid context for NULL() pointer at %%L")); - goto bad_op; + CHECK_INTERFACES + gfc_error ("Invalid context for NULL() pointer at %L", &e->where); + return false; } switch (e->value.op.op) @@ -4227,10 +4233,10 @@ resolve_operator (gfc_expr *e) break; } - snprintf (msg, sizeof (msg), - _("Operand of unary numeric operator %%<%s%%> at %%L is %s"), - gfc_op2string (e->value.op.op), gfc_typename (e)); - goto bad_op; + CHECK_INTERFACES + gfc_error ("Operand of unary numeric operator %<%s%> at %L is %s", + gfc_op2string (e->value.op.op), &e->where, gfc_typename (e)); + return false; case INTRINSIC_PLUS: case INTRINSIC_MINUS: @@ -4244,10 +4250,10 @@ resolve_operator (gfc_expr *e) Defer to a possibly overloading user-defined operator. */ if (!gfc_op_rank_conformable (op1, op2)) { - dual_locus_error = true; - snprintf (msg, sizeof (msg), - _("Inconsistent ranks for operator at %%L and %%L")); - goto bad_op; + CHECK_INTERFACES + gfc_error ("Inconsistent ranks for operator at %L and %L", + &op1->where, &op2->where); + return false; } gfc_type_convert_binary (e, 1); @@ -4255,16 +4261,21 @@ resolve_operator (gfc_expr *e) } if (op1->ts.type == BT_DERIVED || op2->ts.type == BT_DERIVED) - snprintf (msg, sizeof (msg), - _("Unexpected derived-type entities in binary intrinsic " - "numeric operator %%<%s%%> at %%L"), - gfc_op2string (e->value.op.op)); + { + CHECK_INTERFACES + gfc_error ("Unexpected derived-type entities in binary intrinsic " + "numeric operator %<%s%> at %L", + gfc_op2string (e->value.op.op), &e->where); + return false; + } else - snprintf (msg, sizeof(msg), - _("Operands of binary numeric operator %%<%s%%> at %%L are %s/%s"), - gfc_op2string (e->value.op.op), gfc_typename (op1), - gfc_typename (op2)); - goto bad_op; + { + CHECK_INTERFACES + gfc_error ("Operands of binary numeric operator %<%s%> at %L are %s/%s", + gfc_op2string (e->value.op.op), &e->where, gfc_typename (op1), + gfc_typename (op2)); + return false; + } case INTRINSIC_CONCAT: if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER @@ -4275,10 +4286,10 @@ resolve_operator (gfc_expr *e) break; } - snprintf (msg, sizeof (msg), - _("Operands of string concatenation operator at %%L are %s/%s"), - gfc_typename (op1), gfc_typename (op2)); - goto bad_op; + CHECK_INTERFACES + gfc_error ("Operands of string concatenation operator at %L are %s/%s", + &e->where, gfc_typename (op1), gfc_typename (op2)); + return false; case INTRINSIC_AND: case INTRINSIC_OR: @@ -4318,12 +4329,11 @@ resolve_operator (gfc_expr *e) goto simplify_op; } - snpr
Re: [PATCH] Fortran: fix ICE in gfc_create_module_variable [PR100273]
On 9/5/24 12:42 PM, Harald Anlauf wrote: Dear all, the attached simple patch fixes a corner case related to pr84868, which was tracked separately. While Paul's patch for pr84868 added the framework for treating len_trim in the specification part of a character function, it missed the possibility that that function need not appear at the top level of a module, but could be a contained function. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald OK for mainline. Thanks. Jerry
Re: [patch, Fortran] Unsigned constants for ISO_FORTRAN_ENV and ISO_C_BINDING
On 10/12/24 9:04 AM, Thomas Koenig wrote: Hello world, the attached patch implements the constants for UNSIGNED for ISO_FORTRAN_ENV and ISO_C_BINDING. With this, the implementation of UNSIGNED for gfortran should be complete, modulo bugs, of course. OK for trunk? Looks good to go Thomas. Thanks for your efforts! Jerry -- snip --
Re: [Patch] Fortran: Fix translatability of diagnostic strings
On 10/18/24 3:20 PM, Tobias Burnus wrote: *Patch ping* OK for trunk. Jerry Tobias Burnus wrote: I noticed that several diagnostic strings were not tagged as translatable. I fixed them by adding _ or G_ as prefix ( →gcc/ABOUT-GCC-NLS) and moved a single-use string to the message to make it more readable. One error message did not quit fit the pattern, hence, I modified it slightly, and a few '...' should have used proper %<...%> quotes. OK for mainline? Tobias PS: Currently, 'make gcc.pot' fails because of PR117109. This issue has been fixed. Thanks David! Tobias
Re: Fortran: Add range-based diagnostic
On 10/18/24 3:35 PM, Tobias Burnus wrote: This patch was motivated by David's talk at Cauldron – and by getting rather bad locations for some diagnostics, where I wanted to use the column number to ensure that all items are found. The main problem was a missing gobbling of spaces, but still ranges are way nicer. As gfortran uses the common system, that was trivial - except that during parsing something else is used and that therefore need to support two formats, which required a few changes. Still, it is rather non invasive and I think for trans*.cc is also does a nice cleanup. Unsurprisingly, there are more opportunities, both for fixing the location issues due to treating whitespace and ranges instead of a single locus; however, a single location is also fine. Note that for 'a + b' the locus could be '~~1~~', i.e. pointing at '+' but spanning the whole expression. Talking about unused features: besides 'inform' we could also use fixit hints, providing patches. And I note that gfc_error also supports %qD or %qE or ... to print trees. But back to this patch, an example is the following: 27 | deallocate(ALLOCS(1)) | 1 Error: Allocate-object at (1) must be ALLOCATABLE or a POINTER Tested on x86_64-gnu-linux. Comments, suggestions, remarks? OK for mainline? After scanning through the whole long patch I think I get the pattern of it. Looks Good To Me, OK. Jerry Tobias PS: Andre remarked that there was some issue, logged somewhere in Bugzilla, due to the old/current handling of locations. I have not searched Bugzilla and, thus, have no idea whether it helps or not. Presumably not.
[patch, fortran] PR28032 gfortran.dg tests use dg-options with -On even though it is already torture tests
The attached diff file begins some test suite cleanup. The patch removes extra spaces between dg-do and the run directive, I only have gone through gfortran.dg and not its sub-directories. Interestingly, one of the tests fails when this space is removed. I fixed that by adding in a -O in the dg-options. The PR is not about the extra spaces. Interestingly it is recommended in comment #3 that the -O0 which are superfluous be removed everywhere. I plan to make additional passes through the tests to clean out the -O and -O0 directives as suggested and see what the result is. I also plan to go through the sub-directories as well. (ie more patches will follow as I have time.) The effect of removing the extra space is additional tests on the test case are run. [aside: I found one test case that had its executable bit set so I corrected it as well.] Regression tested on x86-64-linux-gnu. OK for trunk? Author: Jerry DeLisle Date: Sat Oct 19 19:29:22 2024 -0700 Fortran: Remove extra space from dg-do run directives. gcc/testsuite/ChangeLog: PR fortran/28031 * gfortran.dg/ISO_Fortran_binding_4.f90: Delete extra space in dg-do run directive. * gfortran.dg/abort_shouldfail.f90: Likewise. * gfortran.dg/adjustl_1.f90: Likewise. * gfortran.dg/allocate_with_mold_3.f90: Likewise. * gfortran.dg/allocate_with_source_6.f90: Likewise. * gfortran.dg/altreturn_9_0.f90: Likewise. * gfortran.dg/array_constructor_52.f90: Likewise. * gfortran.dg/array_constructor_53.f90: Likewise. * gfortran.dg/array_simplify_2.f90: Likewise. * gfortran.dg/array_simplify_3.f90: Likewise. * gfortran.dg/block_14.f90: Likewise. * gfortran.dg/bound_9.f90: Likewise. * gfortran.dg/bounds_check_20.f90: Likewise. * gfortran.dg/c_funptr_1_mod.f90: Likewise. * gfortran.dg/char_result_mod_19.f90: Likewise. * gfortran.dg/coarray_data_1.f90: Likewise. * gfortran.dg/contiguous_8.f90: Likewise. * gfortran.dg/cray_pointers_2.f90: Likewise. * gfortran.dg/cshift_1.f90: Likewise. * gfortran.dg/cshift_2.f90: Likewise. * gfortran.dg/data_derived_1.f90: Likewise. * gfortran.dg/dec_union_12.f90: Remove executable bit from file permissions. * gfortran.dg/dependency_50.f90: Likewise. * gfortran.dg/dependency_51.f90: Likewise. * gfortran.dg/dependency_54.f90: Likewise. * gfortran.dg/derived_init_5.f90: Likewise. * gfortran.dg/dim_sum_1.f90: Likewise. * gfortran.dg/dim_sum_2.f90: Likewise. * gfortran.dg/dim_sum_3.f90: Likewise. * gfortran.dg/eoshift_3.f90: Likewise. * gfortran.dg/eoshift_4.f90: Likewise. * gfortran.dg/eoshift_5.f90: Likewise. * gfortran.dg/eoshift_6.f90: Likewise. * gfortran.dg/execute_command_line_3.f90: Likewise. * gfortran.dg/findloc_5.f90: Likewise. * gfortran.dg/implied_do_io_4.f90: Likewise. * gfortran.dg/implied_do_io_5.f90: Likewise. * gfortran.dg/implied_do_io_6.f90: Likewise. * gfortran.dg/inline_matmul_1.f90: Likewise. * gfortran.dg/inline_matmul_10.f90: Likewise. Add -O option. * gfortran.dg/inline_matmul_11.f90: Likewise. * gfortran.dg/inline_matmul_17.f90: Likewise. * gfortran.dg/inline_matmul_18.f90: Likewise. * gfortran.dg/inline_matmul_19.f90: Likewise. * gfortran.dg/inline_matmul_20.f90: Likewise. * gfortran.dg/inline_matmul_3.f90: Likewise. * gfortran.dg/inline_matmul_4.f90: Likewise. * gfortran.dg/inline_matmul_5.f90: Likewise. * gfortran.dg/inline_matmul_7.f90: Likewise. * gfortran.dg/inline_matmul_8.f90: Likewise. * gfortran.dg/inline_matmul_9.f90: Likewise. * gfortran.dg/intent_out_12.f90: Likewise. * gfortran.dg/internal_readwrite_4.f90: Likewise. * gfortran.dg/is_contiguous_2.f90: Likewise. * gfortran.dg/is_contiguous_3.f90: Likewise. * gfortran.dg/matmul_15.f90: Likewise. * gfortran.dg/matmul_16.f90: Likewise. * gfortran.dg/matmul_19.f90: Likewise. * gfortran.dg/matmul_blas_1.f: Likewise. * gfortran.dg/matmul_bounds_14.f: Likewise. * gfortran.dg/matmul_bounds_15.f: Likewise. * gfortran.dg/matmul_bounds_16.f: Likewise. * gfortran.dg/matmul_const.f90: Likewise. * gfortran.dg/maxloc_4.f90: Likewise. * gfortran.dg/maxval_parameter_1.f90: Likewise. * gfortran.dg/min_max_type.f90: Likewise. * gfortran.dg/min_max_type_2.f90: Likewise. * gfortran.dg/minloc_4.f90: Likewise.
Re: [patch, fortran] PR28032 gfortran.dg tests use dg-options with -On even though it is already torture tests
On 10/20/24 1:16 PM, Harald Anlauf wrote: Hi Jerry! Am 20.10.24 um 21:53 schrieb Jerry D: On 10/20/24 12:23 PM, Harald Anlauf wrote: Hi Jerry! Am 20.10.24 um 18:56 schrieb Jerry D: The attached diff file begins some test suite cleanup. The patch removes extra spaces between dg-do and the run directive, I only have gone through gfortran.dg and not its sub-directories. Interestingly, one of the tests fails when this space is removed. I fixed that by adding in a -O in the dg-options. There was already a discussion of the "two spaces" vs. "one space" version of dg-do run; see e.g. the thread starting here: https://gcc.gnu.org/pipermail/fortran/2024-March/060363.html (see also Andrew's remark: https://gcc.gnu.org/pipermail/fortran/2024-April/060400.html) I learned that the "two spaces" hack^Wversion has its (undocumented) uses, namely a test is only run once. Has anybody attempted to adjust the testsuite documentation? I find the possibility to run a certain test only once interesting, especially if only a runtime library feature is tested, and this saves (a little) testsuite execution time, which I find to have been increasing quite a lot recently. (One of the possible solutions was to have the two spaces, but also a comment that no cycling is intended. As long are there is no other solution to this hack.) I am aware of Andrews comment here. This is my first exploration of the issue. I agree it is a hack and useful. The problem I see is that some cases are deliberate and others by accident of typing. Indeed, it should always be clear from looking at a testcase to tell what was meant. This is why I always add e.g. a "dg-do compile" even when this is the default. I wonder if a better way to do this is a new directive such as "dg-do run-once" At least then it would be clear what is happening. Adding a comment on top of two spaces is like a hack on a hack. Yes, "dg-do run-once" was what I was going to suggest. Including an optional comment explaining why it would be sufficient to just run a particular test once. I found the relevant 'code' in gfortran-dg.exp: # look if this is dg-do run test, in which case # we cycle through the option list, otherwise we don't if [expr [search_for $test "dg-do run"]] { set option_list $torture_with_loops } else { set option_list [list { -O } ] } I think I can tweak this to add in the case of "dg-do run-once" I will give it a try and report back here. The PR is not about the extra spaces. Interestingly it is recommended in comment #3 that the -O0 which are superfluous be removed everywhere. I plan to make additional passes through the tests to clean out the -O and -O0 directives as suggested and see what the result is. I also plan to go through the sub-directories as well. (ie more patches will follow as I have time.) I think that reviewing the appropriateness of the specifications of the tests is a good thing. That should happen before plainly changing the dg-directives. Agree One thing to remember: in the gfortran frontend, cycling through the optimization levels switches several flags controlling e.g. frontend optimization, matmul inlining, ... In particular the test gcc/testsuite/gfortran.dg/inline_matmul_1.f90 *requires* matmul inlining. So you want either run this test only with options that enable this inlining. Optimization is not the point here. And one of the essential points of this test is the last line: ! { dg-final { scan-tree-dump-times "_gfortran_matmul" 0 "optimized" } } Now if you explicitly add -O, what is the point of cycling through the optimization levels? In this one case it was a hack until I figure out a better way to do it other than two blank spaces. :) In the PR I mentioned not wanting to get into the test machinery. I suspect this will be necessary. Yes. Just go ahead... ;-) Always easier said then done, but I will see what happens. ;-) Jerry Cheers, Harald --- snip ---
Re: [patch, fortran] PR28032 gfortran.dg tests use dg-options with -On even though it is already torture tests
On 10/20/24 12:23 PM, Harald Anlauf wrote: Hi Jerry! Am 20.10.24 um 18:56 schrieb Jerry D: The attached diff file begins some test suite cleanup. The patch removes extra spaces between dg-do and the run directive, I only have gone through gfortran.dg and not its sub-directories. Interestingly, one of the tests fails when this space is removed. I fixed that by adding in a -O in the dg-options. There was already a discussion of the "two spaces" vs. "one space" version of dg-do run; see e.g. the thread starting here: https://gcc.gnu.org/pipermail/fortran/2024-March/060363.html (see also Andrew's remark: https://gcc.gnu.org/pipermail/fortran/2024-April/060400.html) I learned that the "two spaces" hack^Wversion has its (undocumented) uses, namely a test is only run once. Has anybody attempted to adjust the testsuite documentation? I find the possibility to run a certain test only once interesting, especially if only a runtime library feature is tested, and this saves (a little) testsuite execution time, which I find to have been increasing quite a lot recently. (One of the possible solutions was to have the two spaces, but also a comment that no cycling is intended. As long are there is no other solution to this hack.) I am aware of Andrews comment here. This is my first exploration of the issue. I agree it is a hack and useful. The problem I see is that some cases are deliberate and others by accident of typing. I wonder if a better way to do this is a new directive such as "dg-do run-once" At least then it would be clear what is happening. Adding a comment on top of two spaces is like a hack on a hack. The PR is not about the extra spaces. Interestingly it is recommended in comment #3 that the -O0 which are superfluous be removed everywhere. I plan to make additional passes through the tests to clean out the -O and -O0 directives as suggested and see what the result is. I also plan to go through the sub-directories as well. (ie more patches will follow as I have time.) I think that reviewing the appropriateness of the specifications of the tests is a good thing. That should happen before plainly changing the dg-directives. Agree One thing to remember: in the gfortran frontend, cycling through the optimization levels switches several flags controlling e.g. frontend optimization, matmul inlining, ... In particular the test gcc/testsuite/gfortran.dg/inline_matmul_1.f90 *requires* matmul inlining. So you want either run this test only with options that enable this inlining. Optimization is not the point here. And one of the essential points of this test is the last line: ! { dg-final { scan-tree-dump-times "_gfortran_matmul" 0 "optimized" } } Now if you explicitly add -O, what is the point of cycling through the optimization levels? In this one case it was a hack until I figure out a better way to do it other than two blank spaces. :) In the PR I mentioned not wanting to get into the test machinery. I suspect this will be necessary. Cheers, Harald --- snip ---
PR105361 Fix of testcase
Pushed as stated in the PR to cleanup the test case. commit 6604a05fa27bc21c3409e767552daca3fcf43964 (HEAD -> master, origin/master, origin/HEAD) Author: Jerry DeLisle Date: Thu Oct 17 13:39:09 2024 -0700 Fortran: Add tolerance to real value comparisons. gcc/testsuite/ChangeLog: PR fortran/105361 * gfortran.dg/pr105361.f90: In the comparisons of real values after a read, use a tolerance so that subtle differences in results between different architectures do not fail.
Re: [patch, fortran] Fix ICE with use of INT32 et al from ISO_FORTRAN_ENV
On 10/17/24 12:52 PM, Thomas Koenig wrote: Hello world, The attached patch fixes an ICE when an UNSIGNED-specific constant is used from ISO_FORTRAN_ENV. The error message is not particularly great, it is Error: Unsigned: The symbol 'uint32', referenced at (1), is not in the selected standard but it is better than an ICE. OK for trunk? Looks good to me, yes OK. Jerry Best regards Thomas gcc/fortran/ChangeLog: * error.cc (notify_std_msg): Handle GFC_STD_UNSIGNED. gcc/testsuite/ChangeLog: * gfortran.dg/unsigned_37.f90: New test.
Re: [PATCH] Fortran: fix several front-end memleaks
On 10/29/24 2:00 PM, Harald Anlauf wrote: Dear all, while looking at the recent testcase gfortran.dg/pr115070.f90 with f951 running under valgrind, I noticed minor front-end memleaks of gfc_expr's that are probably fallout from a code refactoring, which are fixed by the attached. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Yes OK for mainline. Thanks, Jerry
Re: [Patch, fortran] PR115700 - comment 5: uninitialized string length in ASSOCIATE
On 10/30/24 9:58 AM, Steve Kargl wrote: On Wed, Oct 30, 2024 at 04:41:40PM +, Paul Richard Thomas wrote: This wrinkle to PR115700 came about because the associate-name string length was not being initialized, when an array selector had a substring reference with non-constant start or end. This, of course, caused subsequent references to fail. The ChangeLog provides an adequate explanation of the attached patch. OK for mainline and backporting to 14-branch? Yes. Thanks for the patch. The comment in the test case refers to a tmp4. There is no tmp4 referenced in the test case. Jerry
Re: [patch, Fortran] Introduce unsigned versions of MASKL and MASKR
On 11/2/24 8:44 AM, Thomas Koenig wrote: Ping **(5./7.) ? MASKR and MASKL are obvious candidates for unsigned, too; in the previous version of the doc patch, I had promised that these would take unsigned arguments in the future. What I had in mind was they could take an unsigned argument and return an unsigned result. Thinking about this a bit more, I realized that this was actually a bad idea; nowhere else do we allow UNSIGNED for bit counting, and things like checking for negative number of bits (which is illegal) would not work. Hence, two new intrinsics, UMASKL and UMASKR. Regressoin-tesed (and this time, I added the intrinsics to the list, so no trouble expected there :-) OK for trunk? Yes, LGTM Jerry
Re: [Patch, fortran] PR105054 - [12/13/14/15 Regression] Using one kind of pointer functions causes the compiler to hang since r11-3029-g2b0df0a6ac79b34f
On 11/12/24 5:23 AM, Paul Richard Thomas wrote: Hi All, The ChangeLog and comment make it clear what this patch does and why. OK for mainline and backporting after a week or so? Regards Paul In the test case: A comment s/resul/result/ Also the test conditional if (trim (array_strings2(i)) /= trim(chr(i))) print *, i, trim(array_strings2(i)), ' xx ',trim (chr(i)) Change print to a STOP ? Otherwise looks good to me and OK Jerry
Re: [PATCH] gfortran testsuite: Remove unit-files in files having open-statements, PR116701
On 9/23/24 11:21 PM, Hans-Peter Nilsson wrote: Here's a general approach to handle PR116701. I considered adding manual deletions as quoted below and mentioned in the PR, but seeing the handling of "integer 8" in fortran-torture-execute I decided to follow that example: better scan the source for open-statements than relying on manual annotations and people remembering to add them for new test-cases. I hope the inclusion of gfortran-dg.exp in fortran-torture.exp is not controversial, but there's no fortran-specific testsuite file common to dg and classic-torture and also this placement is still in the "Utility routines" section of gfortran-dg.exp. (BTW, the C torture-tests changed to the dg framework some time ago - no more .x-files there and dg-directives actually work - there are some in gfortran.fortran-torture that are apparently ignored!) Explain this change of including gfortran-dg.exp in fortran-torture.exp. What does it mean in the case I do 'make -k -j4 check-fortran'? Does gfortran-dg-exp get performed twice? Forgive my ignorance of the testsuite incantations. Regards, Jerry
Re: [patch, fortran] Implement IANY, IALL and IPARITY for unsigned
On 9/18/24 1:20 PM, Thomas Koenig wrote: OK for trunk? OK and thanks. Jerry --- snip ---
Re: [PATCH] gfortran testsuite: Remove unit-files in files having open-statements, PR116701
On 9/24/24 5:46 PM, Hans-Peter Nilsson wrote: Thanks for the review! Date: Tue, 24 Sep 2024 17:10:27 -0700 Cc: Jerry D From: Jerry D On 9/23/24 11:21 PM, Hans-Peter Nilsson wrote: I hope the inclusion of gfortran-dg.exp in fortran-torture.exp is not controversial, but there's no fortran-specific testsuite file common to dg and classic-torture and also this placement is still in the "Utility routines" section of gfortran-dg.exp. (BTW, the C torture-tests changed to the dg framework some time ago - no more .x-files there and dg-directives actually work - there are some in gfortran.fortran-torture that are apparently ignored!) Explain this change of including gfortran-dg.exp in fortran-torture.exp. I need to put the new proc in a file, to be used by both dg and classic-torture. I picked among the untility-carrying files gfortran-dg.exp, as it looked more fitting than e.g. fortran-modules.exp. Since it's not previously included there, I included that file in fortran-torture.exp. By including that file, not just the new proc gfortran-dg-rmunits but also the other procs in that file are available. Since they don't collide with the fortran-torture machinery, that should have no effect. What does it mean in the case I do 'make -k -j4 check-fortran'? Does gfortran-dg-exp get performed twice? (I assume you mean "are the gfortran.dg tests run twice" as other interpretations make less sense to me.) Your interpretation of my typo is correct. Along with Andre I like auto cleanup. On new test cases we try to have them self delete whether they pass or fail. So your changes are ok with me. No. Forgive my ignorance of the testsuite incantations. There's nothing but load_lib and proc definitions in gfortran-dg.exp, specifically no "top-level code" running tests like execute.exp or dg.exp, so including it should have no such effect...but I see that the files it include *do* have top-level code (setting global variables for use by the testsuite machinery, *not* running tests). Perhaps I should ignore that misnomer and put gfortran-dg-rmunits in fortran-modules.exp in order to put pollution worries to rest. After all, that file already has the utility proc igrep, used in gfortran-dg-rmunits. So, new version coming up. brgds, H-P
[patch, fortran] PR117765 Impure function within a BLOCK construct within a DO CONCURRENT
I would like to commit the attached patch for Steve. Regression tested on x86-64-linux-gnu. OK for trunk? Author: Steve Kargl Date: Sun Nov 24 18:26:03 2024 -0800 Fortran: Check IMPURE in BLOCK inside DO CONCURRENT. PR fortran/117765 gcc/fortran/ChangeLog: * resolve.cc (check_pure_function): Check the stack too see if there in a nested BLOCK and, if that block is in a DO_CONCURRENT, issue an error. gcc/testsuite/ChangeLog: * gfortran.dg/impure_fcn_do_concurrent.f90: New test. diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index b8c908b51e9..1b98be205b4 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -3228,6 +3228,24 @@ pure_stmt_function (gfc_expr *e, gfc_symbol *sym) static bool check_pure_function (gfc_expr *e) { const char *name = NULL; + code_stack *stack; + bool saw_block = false; + + /* A BLOCK construct within a DO CONCURRENT construct leads to + gfc_do_concurrent_flag = 0 when the check for an impure function + occurs. Check the stack to see if the source code has a nested + BLOCK construct. * + for (stack = cs_base; stack; stack = stack->prev) +{ + if (stack->current->op == EXEC_BLOCK) saw_block = true; + if (saw_block && stack->current->op == EXEC_DO_CONCURRENT) + { + gfc_error ("Reference to impure function at %L inside a " + "DO CONCURRENT", &e->where); + return false; + } +} + if (!gfc_pure_function (e, &name) && name) { if (forall_flag) diff --git a/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 new file mode 100644 index 000..07b5a37f978 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/impure_fcn_do_concurrent.f90 @@ -0,0 +1,31 @@ +! +! { dg-do compile } +! +program foo + + implicit none + + integer i + integer :: j = 0 + real y(4) + + do concurrent(i=1:4) + y(i) = bar(i)! { dg-error "Reference to impure function" } + end do + + do concurrent(i=1:4) + block + y(i) = bar(i) ! { dg-error "Reference to impure function" } + end block + end do + + contains + + impure function bar(i) + real bar + integer, intent(in) :: i + j = j + i + bar = j + end function bar + +end program foo
Re: [Patch, fortran] PR117763 [15.0 regression] segmentation fault through allocatable char arrays (?)
On 11/25/24 3:09 AM, Paul Richard Thomas wrote: Hi All, The breakage was caused by the patch for PR109345. As it happens, this part of the patch was not required to fix the PR and looked to be a considerable simplification of the condition. Although correct that all is left are class dummies, it caused the regression by not checking that it is a class array reference. Regtested on mainline. OK to apply to all affected branches after regtesting the backports? Regards Paul Fortran: Partial reversion of patch for pr109345 [PR117763] 2024-11-25 Paul Thomas mailto:pa...@gcc.gnu.org>> gcc/fortran PR fortran/117763 * trans-array.cc (gfc_get_array_span): Guard against derefences of 'expr'. Clean up some typos. Use 'gfc_get_vptr_from_expr' for clarity and apply a functional reversion of last section that deals with class dummies. gcc/testsuite/ PR fortran/117763 * gfortran.dg/pr117763.f90: New test. OK Paul, thanks for quick fix. Jerry
Re: [PATCH] Fortran: fix crash with bounds check writing array section [PR117791]
On 11/27/24 12:31 PM, Harald Anlauf wrote: Dear all, the attached patch fixes a wrong-code issue with bounds-checking enabled when doing I/O of an array section and an index is either an expression or a function result. The problem does not occur without bounds-checking. When looking at the original testcase, the function occuring in the affected index was evaluated twice, once with wrong arguments. The most simple solution appears to fall back to scalarization with bounds-checking enabled. If someone has a quick idea to handle this better, please speak up! Regtested on x86_64-pc-linux-gnu. OK for mainline? This seems to be a 14/15 regression, so a backport is advisable. Thanks, Harald The patch looks OK to me. I wonder if this fall back to the scalarizer should be done everywhere if a a user has specified bounds checking, what is the point of optimizing array references? If the code works in 13 maybe we need to isolate to what broke it and intervene at that place. Also go ahead with back porting if no other ideas pop up. I just fear we are covering up something else. Jerry
Re: [PATCH] Fortran: fix checking of protected variables in submodules [PR83135]
On 11/20/24 1:08 PM, Harald Anlauf wrote: Dear all, the attached, actually rather straightforward patch fixes the checking of protected variables in submodules. When a variable was use-associated in an ancestor module, we failed to properly diagnose this. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Yes, looks good to go. Jerry
Re: [PATCH] Fortran: fix passing of NULL() actual argument to character dummy [PR104819]
On 11/13/24 2:26 PM, Harald Anlauf wrote: Dear all, the attached patch is the third part of a series to fix the handling of NULL() passed to pointer dummy arguments. This one addresses character dummy arguments (scalar, assumed-shape, assumed-rank) for various uses in the caller. The patch is a little larger than I expected, due to corner cases (MOLD present or not, assumed-rank or other). If someone finds a more clever version, I would be happy to learn about it. Especially the treatment of assumed-rank dummy could certainly be done differently. Regtested on x86_64-pc-linux-gnu. OK for mainline? As this fixes wrong code on the one hand, and is very localized, I would like to backport this to 14-branch after some waiting. Is this ok? Thanks, Harald OK for mainline and backport. Food for thought at another time: gfc_conv_procedure_call contains about 2100 lines of code. One can read through this fairly directly and the comments are very helpful. It begs for some refactoring into a set of smaller functions. Kind and Type regards, Jerry
Re: [PATCH] Fortran: add bounds-checking for ALLOCATE of CHARACTER with type-spec [PR53357]
On 11/17/24 2:21 PM, Harald Anlauf wrote: Dear all, the attached patch fixes a rejects-valid / rejects-potentially-valid code issue for ALLOCATE of CHARACTER with type-spec, and add character length checking with -fcheck=bounds for the case at hand. It also improves checking of character function declarations and references slightly, using the diagnostics of NAG as a guidance. Some testcases popped up during regtesting, suggesting that one needs to be careful not to generate too many false positives, so I decided to not spend to much time on the FIXME's therein. (Character length might be expressions in an explicit interface and the actual declaration, where we don't have a reliable way to compare.) Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Looks good, OK for mainline. Jerry
[wwwdocs] Fortran changes, add description regarding commas in formats
Suggested docs change regarding fix to PR88052. See attached diff file. OK to push? Regards, Jerry diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html index 46dad391..2dc222e3 100644 --- a/htdocs/gcc-15/changes.html +++ b/htdocs/gcc-15/changes.html @@ -143,6 +143,10 @@ a work-in-progress. >gfortran documentation for details. These have been proposed (https://j3-fortran.org/doc/year/24/24-116.txt";>J3/24-116) for inclusion in the next Fortran standard. + Missing commas separating descriptors in input/output format strings are no + longer permitted by default and are rejected at run-time unless -std=legacy + is used at compile time. See Fortran 2023 constraint C1302. +
Re: [wwwdocs] Fortran changes, add description regarding commas in formats
On 11/23/24 10:59 AM, Harald Anlauf wrote: Am 23.11.24 um 19:35 schrieb Jerry D: Suggested docs change regarding fix to PR88052. See attached diff file. OK to push? Regards, Jerry Jerry, for clarification: isn't it the language standard option used when compiling the main that is relevant? The main might be compiled separately from a module containing the offending legacy code, where it may or may not be diagnosed at compile time. Otherwise OK from my side. Thanks, Harald Indeed, only the -std= specified on the main program unit is relevant. I will clarify this in my description. I am working on a separate patch that will check the format strings at compile time when possible. We do not check format strings in character variables at compile time and I am not planning to this. (It might be possible in a translation or resolve stage if the character variable is a constant). I will update and push this doc change. Thanks Herald.
[patch, libgfortran] PR117820
Hi all, Attached patch adds a test for zero that is needed for write_boz to work correctly. Almost obvious. Regression tested on x86_64. Ok for trunk? Jerry Author: Jerry DeLisle Date: Mon Dec 2 19:45:26 2024 -0800 Fortran: Fix B64.0 formatted write output. PR fortran/117820 libgfortran/ChangeLog: * io/write.c (write_b): Add test for zero needed by write_boz. gcc/testsuite/ChangeLog: * gfortran.dg/pr117820.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr117820.f90 b/gcc/testsuite/gfortran.dg/pr117820.f90 new file mode 100644 index 000..e873393f2ef --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr117820.f90 @@ -0,0 +1,12 @@ +! { dg-do run } +! { dg-options "-std=gnu" } +! see pr117820, -std=gnu for this test needed to avoid a warning with -pedantic +! on line 9 below. +program test + integer(8) :: x + character(80) :: output + output = "garbage" + x = -huge(x) - 1_8 + write(output, '("<",B64.0,">")') x + if (output .ne. "<1000>") stop 1 +end program diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c index 2f414c6b57d..ccb2b5cb810 100644 --- a/libgfortran/io/write.c +++ b/libgfortran/io/write.c @@ -1392,6 +1392,10 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len) { n = extract_uint (source, len); p = btoa (n, itoa_buf, sizeof (itoa_buf)); + + /* Test for zero. Needed by write_boz. */ + if (n != 0) + n = 1; write_boz (dtp, f, p, n, len); } }
Re: [PATCH] Fortran: Added support for locality specs in DO CONCURRENT (Fortran 2018/23)
On 9/23/24 1:00 AM, Andre Vehreschild wrote: Hi Anuj, please check the code style of your patch using: contrib/check_GNU_style.py It reports several errors with line length and formatting. I am going to work with Tobias to move this along. I have the style things fixed. I am going to work my way up the emails with comments and see where we get. Jerry
Re: [Ping, Fortran, Patch, PR116669, v1] Fix ICE in deallocation of derived types having cyclic dependencies
On 1/6/25 2:06 AM, Andre Vehreschild wrote: Hi all, pinging attached rebased patch. Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? - Andre On Thu, 12 Dec 2024 14:50:13 +0100 Andre Vehreschild wrote: Hi all, attached patch improves analysis of cycles in derived types, i.e. type dependencies ala: type(T) type(T2), allocatable :: c end type type(T2) type(T), allocatable :: t end type are now detected and deallocating an object that is of any of the types now no longer crashes the compiler because of an endless recursion. To accomplish this, I stored the symbols of the types seen in a C++ set and checked if a component's type is already present in there. When a type has such an indirect self-reference, it gets marked by setting its symbol_attribute::recursive flag. Later steps then can make use of it. Furthermore are _deallocate members of the vtab populated when a type has the recursive and the alloc_comp flag set. Bootstraps and regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? This one is good to go. Jerry Note: The patch was developed on top of my coarray patch, but should apply with delta on a regular trunk w/o issues. Regards, Andre -- Andre Vehreschild * Email: vehre ad gcc dot gnu dot org -- Andre Vehreschild * Email: vehre ad gmx dot de
Re: [-Ping-, Fortran, Patch, PR116669, v3] Fix ICE in deallocation of derived types having cyclic dependencies
On 1/6/25 6:21 AM, Andre Vehreschild wrote: Hi all, during looking for something completely different, I figured, that gcc does not use std::set internally, but its implementation of hash_set. I therefore adapted the patch to use it. Nothing more changed. Still regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? ... and this tweak is OK. Proceed. Jerry Regards, Andre On Mon, 6 Jan 2025 11:06:46 +0100 Andre Vehreschild wrote: Hi all, pinging attached rebased patch. Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? - Andre On Thu, 12 Dec 2024 14:50:13 +0100 Andre Vehreschild wrote: Hi all, attached patch improves analysis of cycles in derived types, i.e. type dependencies ala: type(T) type(T2), allocatable :: c end type type(T2) type(T), allocatable :: t end type are now detected and deallocating an object that is of any of the types now no longer crashes the compiler because of an endless recursion. To accomplish this, I stored the symbols of the types seen in a C++ set and checked if a component's type is already present in there. When a type has such an indirect self-reference, it gets marked by setting its symbol_attribute::recursive flag. Later steps then can make use of it. Furthermore are _deallocate members of the vtab populated when a type has the recursive and the alloc_comp flag set. Bootstraps and regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? Note: The patch was developed on top of my coarray patch, but should apply with delta on a regular trunk w/o issues. Regards, Andre -- Andre Vehreschild * Email: vehre ad gcc dot gnu dot org -- Andre Vehreschild * Email: vehre ad gmx dot de -- Andre Vehreschild * Email: vehre ad gmx dot de
Re: [Ping, Fortran, Patch, PR114612, v1] Fix missing deep-copy for allocatable components of derived types having cycles.
On 1/6/25 2:08 AM, Andre Vehreschild wrote: Hi all, attached patch has been rebased to latest trunk. Just pinging! Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? - Andre On Fri, 13 Dec 2024 12:10:58 +0100 Andre Vehreschild wrote: 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? Yes, OK. Thanks. Jerry Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de -- Andre Vehreschild * Email: vehre ad gmx dot de
Re: [Fortran, Patch, PR117643] Implement F_C_STRING()
Attached is the revised patch incorporating handling of optional arguments of a calling procedure and simplified checking for C interoperability. See the PR for much discussion. Regression tested on x86_64_linux_gnu. Two test cases. OK for trunk? Author: Steven G. Kargl Date: Sun Dec 29 14:19:18 2024 -0800 Fortran: Implement f_c_string function. Fortran 2023 has added the new intrinsic function F_C_STRING to convert fortran strings of default character kind to a null terminated C string. Contributions from Steve Kargl, Harald Anlauf, FX Coudert, Mikael Morin, and Jerry DeLisle. PR fortran/117643 gcc/fortran/ChangeLog: * check.cc (gfc_check_f_c_string): Check arguments of f_c_string(). * gfortran.h (enum gfc_isym_id): New symbol GFC_ISYM_F_C_STRING. * intrinsic.cc (add_functions): Add the ISO C Binding routine f_c_string(). Wrap nearby long line to less than 80 characters. * intrinsic.h (gfc_check_f_c_string): Prototype for gfc_check_f_c_string(). * iso-c-binding.def (NAMED_FUNCTION): Declare for ISO C Binding routine f_c_string(). * primary.cc (gfc_match_rvalue): Fix comment that has been untrue since 2011. Add ISOCBINDING_F_C_STRING to conditional. * trans-intrinsic.cc (conv_trim): Specialized version of trim() for f_c_string(). (gfc_conv_intrinsic_function): Use GFC_ISYM_F_C_STRING to trigger in-lining. gcc/testsuite/ChangeLog: * gfortran.dg/f_c_string1.f90: New test. * gfortran.dg/f_c_string2.f90: New test. diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc index f4fde83e8ab..08cc88ba7cb 100644 --- a/gcc/fortran/check.cc +++ b/gcc/fortran/check.cc @@ -1829,6 +1829,42 @@ gfc_check_image_status (gfc_expr *image, gfc_expr *team) } +/* Check the arguments for f_c_string. */ + +bool +gfc_check_f_c_string (gfc_expr *string, gfc_expr *asis) +{ + + if (gfc_invalid_null_arg (string)) +return false; + + if (!scalar_check (string, 0)) +return false; + + if (string->ts.type != BT_CHARACTER + || (string->ts.type == BT_CHARACTER + && (string->ts.kind != gfc_default_character_kind))) +{ + gfc_error ("%qs argument of %qs intrinsic at %L shall have " + "a type of CHARACTER(KIND=C_CHAR)", + gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic, + &string->where); + return false; +} + + if (asis) +{ + if (!type_check (asis, 1, BT_LOGICAL)) + return false; + + if (!scalar_check (asis, 1)) + return false; +} + + return true; +} + + bool gfc_check_failed_or_stopped_images (gfc_expr *team, gfc_expr *kind) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 87307c5531e..a2c8ebc6b3e 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -508,6 +508,7 @@ enum gfc_isym_id GFC_ISYM_EXP, GFC_ISYM_EXPONENT, GFC_ISYM_EXTENDS_TYPE_OF, + GFC_ISYM_F_C_STRING, GFC_ISYM_FAILED_IMAGES, GFC_ISYM_FDATE, GFC_ISYM_FE_RUNTIME_ERROR, diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc index a2e241280c3..d4db6abe7b4 100644 --- a/gcc/fortran/intrinsic.cc +++ b/gcc/fortran/intrinsic.cc @@ -3145,6 +3145,14 @@ add_functions (void) x, BT_UNKNOWN, 0, REQUIRED); make_from_module(); + add_sym_2 ("f_c_string", GFC_ISYM_F_C_STRING, CLASS_TRANSFORMATIONAL, + ACTUAL_NO, + BT_CHARACTER, dc, GFC_STD_F2023, + gfc_check_f_c_string, NULL, NULL, + stg, BT_CHARACTER, dc, REQUIRED, + "asis", BT_CHARACTER, dc, OPTIONAL); + make_from_module(); + add_sym_1 ("c_sizeof", GFC_ISYM_C_SIZEOF, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, gfc_index_integer_kind, GFC_STD_F2008, gfc_check_c_sizeof, gfc_simplify_sizeof, NULL, @@ -3301,7 +3309,8 @@ add_functions (void) make_generic ("transpose", GFC_ISYM_TRANSPOSE, GFC_STD_F95); - add_sym_1 ("trim", GFC_ISYM_TRIM, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_CHARACTER, dc, GFC_STD_F95, + add_sym_1 ("trim", GFC_ISYM_TRIM, CLASS_TRANSFORMATIONAL, ACTUAL_NO, + BT_CHARACTER, dc, GFC_STD_F95, gfc_check_trim, gfc_simplify_trim, gfc_resolve_trim, stg, BT_CHARACTER, dc, REQUIRED); diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index 61d85eedc69..640d1bc15eb 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -71,6 +71,7 @@ bool gfc_check_dshift (gfc_expr *, gfc_expr *, gfc_expr *); bool gfc_check_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); bool gfc_check_dtime_etime (gfc_expr *); bool gfc_check_event_query (gfc_expr *, gfc_expr *, gfc_expr *); +bool gfc_check_f_c_string (gfc_expr *, gfc_expr *); bool gfc_check_failed_or_stopped_images (gfc_expr *, gfc_expr *); bool gfc_check_fgetputc (gfc_expr *, gfc_expr *); bool gfc_check_fgetput (gfc_expr *); diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def index bad66b1dcbc..5ef4368222c 100644 --- a/gcc/fortran/iso-c-bind
Re: [Fortran, Patch, PR117643] Implement F_C_STRING()
On 12/30/24 12:34 AM, Paul Richard Thomas wrote: Hi Jerry, With such an illustrious group of contributors, I can hardly say 'no', can I? :-) It looks fine to me - OK for trunk. Regards Paul Thanks Paul. Special thanks to Steve for taking this on. commit efc0981077a70c4de4596f682c4aeade07ec2f17 (HEAD -> master, origin/master, origin/HEAD) Author: Steven G. Kargl Date: Sun Dec 29 14:19:18 2024 -0800 Fortran: Implement f_c_string function. On Sun, 29 Dec 2024 at 23:10, Jerry D <mailto:jvdelis...@gmail.com>> wrote: Attached is the revised patch incorporating handling of optional arguments of a calling procedure and simplified checking for C interoperability. See the PR for much discussion. Regression tested on x86_64_linux_gnu. Two test cases. OK for trunk? Author: Steven G. Kargl mailto:kar...@comcast.net>> Date: Sun Dec 29 14:19:18 2024 -0800 Fortran: Implement f_c_string function. Fortran 2023 has added the new intrinsic function F_C_STRING to convert fortran strings of default character kind to a null terminated C string. Contributions from Steve Kargl, Harald Anlauf, FX Coudert, Mikael Morin, and Jerry DeLisle. PR fortran/117643 gcc/fortran/ChangeLog: * check.cc (gfc_check_f_c_string): Check arguments of f_c_string(). * gfortran.h (enum gfc_isym_id): New symbol GFC_ISYM_F_C_STRING. * intrinsic.cc (add_functions): Add the ISO C Binding routine f_c_string(). Wrap nearby long line to less than 80 characters. * intrinsic.h (gfc_check_f_c_string): Prototype for gfc_check_f_c_string(). * iso-c-binding.def (NAMED_FUNCTION): Declare for ISO C Binding routine f_c_string(). * primary.cc (gfc_match_rvalue): Fix comment that has been untrue since 2011. Add ISOCBINDING_F_C_STRING to conditional. * trans-intrinsic.cc (conv_trim): Specialized version of trim() for f_c_string(). (gfc_conv_intrinsic_function): Use GFC_ISYM_F_C_STRING to trigger in-lining. gcc/testsuite/ChangeLog: * gfortran.dg/f_c_string1.f90: New test. * gfortran.dg/f_c_string2.f90: New test.
Re: [patch, fortran] Add modular exponentiation for unsigned
On 2/3/25 11:55 AM, Thomas Koenig wrote: Hello world, with the following patch to the failing test case diff --git a/gcc/testsuite/gfortran.dg/unsigned_15.f90 b/gcc/testsuite/ gfortran.dg/unsigned_15.f90 index da4ccd2dc17..80a7a54e380 100644 --- a/gcc/testsuite/gfortran.dg/unsigned_15.f90 +++ b/gcc/testsuite/gfortran.dg/unsigned_15.f90 @@ -6,8 +6,8 @@ program main unsigned :: u print *,1 + 2u ! { dg-error "Operands of binary numeric operator" } print *,2u + 1 ! { dg-error "Operands of binary numeric operator" } - print *,2u ** 1 ! { dg-error "Exponentiation not valid" } - print *,2u ** 1u ! { dg-error "Exponentiation not valid" } + print *,2u ** 1 ! { dg-error "Operands of binary numeric operator" } + print *,2u ** 1u print *,1u < 2 ! { dg-error "Inconsistent types" } print *,int(1u) < 2 end program main the patch posted to https://gcc.gnu.org/pipermail/fortran/2025-February/061670.html and https://gcc.gnu.org/pipermail/gcc-patches/2025-February/674931.html passes (I don't want to re-submit the whole thing). OK for trunk? Best regards Thomas Yes, please proceed. Jerry
Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]
On 2/3/25 2:14 PM, Vincent Vanlaer wrote: Hi all, Gentle ping for the patch below: https://gcc.gnu.org/pipermail/ fortran/2024-December/061467.html Best wishes, Vincent On 30/12/2024 00:19, Vincent Vanlaer wrote: The -MT and -MQ options should replace the default target in the generated dependency file. deps_add_target needs to be called before cpp_read_main_file, otherwise the original object name is added. gcc/fortran/ PR fortran/47485 * cpp.cc: fix -MT/-MQ adding additional target instead of replacing the default gcc/testsuite/ PR fortran/47485 * gfortran.dg/dependency_generation_1.f90: New test Signed-off-by: Vincent Vanlaer --- gcc/fortran/cpp.cc | 18 -- .../gfortran.dg/dependency_generation_1.f90 | 15 +++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/ dependency_generation_1.f90 diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc index 7c5f00cfd69..3b93d17b90f 100644 --- a/gcc/fortran/cpp.cc +++ b/gcc/fortran/cpp.cc @@ -96,6 +96,8 @@ struct gfc_cpp_option_data int deps_skip_system; /* -MM */ const char *deps_filename; /* -M[M]D */ const char *deps_filename_user; /* -MF */ + const char *deps_target_filename; /* -MT / -MQ */ + bool quote_deps_target_filename; /* -MQ */ int deps_missing_are_generated; /* -MG */ int deps_phony; /* -MP */ int warn_date_time; /* -Wdate-time */ @@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int decoded_options_count, gfc_cpp_option.deps_missing_are_generated = 0; gfc_cpp_option.deps_filename = NULL; gfc_cpp_option.deps_filename_user = NULL; + gfc_cpp_option.deps_target_filename = NULL; + gfc_cpp_option.quote_deps_target_filename = false; gfc_cpp_option.multilib = NULL; gfc_cpp_option.prefix = NULL; @@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED case OPT_MQ: case OPT_MT: - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code; - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg; - gfc_cpp_option.deferred_opt_count++; + gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ); + gfc_cpp_option.deps_target_filename = arg; break; case OPT_P: @@ -593,6 +596,12 @@ gfc_cpp_init_0 (void) } gcc_assert(cpp_in); + + if (gfc_cpp_option.deps_target_filename) + if (mkdeps *deps = cpp_get_deps (cpp_in)) + deps_add_target (deps, gfc_cpp_option.deps_target_filename, + gfc_cpp_option.quote_deps_target_filename); + if (!cpp_read_main_file (cpp_in, gfc_source_file)) errorcount++; } @@ -635,9 +644,6 @@ gfc_cpp_init (void) else cpp_assert (cpp_in, opt->arg); } - else if (opt->code == OPT_MT || opt->code == OPT_MQ) - if (mkdeps *deps = cpp_get_deps (cpp_in)) - deps_add_target (deps, opt->arg, opt->code == OPT_MQ); } /* Pre-defined macros for non-required INTEGER kind types. */ diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 b/ gcc/testsuite/gfortran.dg/dependency_generation_1.f90 new file mode 100644 index 000..d42a257f83a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 @@ -0,0 +1,15 @@ +! This test case ensures that the -MT flag is correctly replacing the object name in the dependency file. +! See PR 47485 +! +! Contributed by Vincent Vanlaer +! +! { dg-do preprocess } +! { dg-additional-options "-cpp" } +! { dg-additional-options "-M" } +! { dg-additional-options "-MF deps" } +! { dg-additional-options "-MT obj.o" } + +module test +end module + +! { dg-final { scan-file "deps" "obj.o:.*" } } Do you have commit rights to gcc? I did not catch your original post. Jerry
Re: [PATCH] Fortran: different character lengths in array constructor [PR93289]
On 2/3/25 2:49 AM, Richard Sandiford wrote: Steve Kargl writes: On Sat, Feb 01, 2025 at 09:49:17PM +0100, Harald Anlauf wrote: Am 01.02.25 um 21:03 schrieb Steve Kargl: On Sat, Feb 01, 2025 at 07:25:51PM +0100, Harald Anlauf wrote: the attached patch downgrades different constant character lengths in an array constructor from a GNU to a legacy extension, so that users get a warning with -std=gnu. We continue to generate an error when standard conformance is requested. Regtested on x86_64-pc-linux-gnu (found one testcase where this triggered... :) OK for mainline? My vote is 'no'. This is either a GNU extension or an error. It is certainly not a legacy issue as array constructors simple cannot appear old moldy *legacy* codes. legacy /= moldy. My intention is to downgrade existing, potentially dangerous GNU extensions (like this one) carefully to "legacy", but not with an axe. I would be in favor of making it a hard error. If you believe gfortan must be able to compile invalid source, then add an option such as -fallow-invalid-scalar-character-entities-in-array-constructor. I don't see why we shall scare users by making code that is currently accepted silently, because it is a GNU extension, suddenly to a hard error. So why must we be so tough? Because -std=legacy allows a whole bunch of garbage. Instead of fixing broken code, a user will slap -std=legacy in a Makefile and move on. Then years from now, you'll see -std=legacy in a whole bunch of Makefiles whether it is needed or not. See -maligned-double and -fallow-argument-mismatch as poster children. I agree that this is what will happen. But for people running benchmarks, it's kind-of (kind-of) a feature. Benchmarks tend to include relatively old code by the time that they're released, and benchmarks continue to be relevant (or at least widely tested) after they're out of maintenance. So it has been really useful to have -std=legacy accept old, dangerous code, since it means that we can continue to test old benchmarks with newer compilers. Improving the benchmark source to avoid the dangerous constructs would invalidate the test and make it harder to compare with historical results. Again, just my $0.02. Same here, just wanted to raise the benchmark use case. Thanks, Richard I think we have had good discussion and for sake of the good of the order I recommend we push this for now. The work has been done. Regards, Jerry
Re: [patch, libfortran] PR114618 Version 2 Format produces incorrect output when contains 1x, ok when uses " "
On 1/29/25 10:30 AM, Jerry D wrote: Follow-up: On 1/28/25 1:33 PM, Harald Anlauf wrote: Jerry, while I haven't read your actual patch yet, I think the testcase is slightly incorrect. In fact, Intel, NAG, Nvidia and AMD flang disagree with it. --- snip --- The following adjustment to the patch puts this right. case FMT_X: case FMT_TR: consume_data_flag = 0; dtp->u.p.skips += f->u.n; tab_pos = bytes_used + dtp->u.p.skips - 1; dtp->u.p.pending_spaces = tab_pos - dtp->u.p.max_pos + 1; dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? f->u.n : dtp->u.p.pending_spaces; //if (t == FMT_X && tab_pos < dtp->u.p.max_pos) //{ //write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces); //dtp->u.p.skips = dtp->u.p.pending_spaces = 0; //} Interestingly, it also fixes a floating point exception I ran into while setting up another test case for part 2 of this effort. I suspect this may be what was detected by the auto patch tester. I will clean this up, adjust the test case for this part and re-submit. Regards, Jerry Here is version 2 of the patch cleaned up and with the test case revised accordingly. Thank you Herald for helping with my blindness. Regressions tested on x86_64. I will wait a bit to see if the auto patch tester reports anything. Otherwise, OK for trunk? Regards, Jerry PS working on part 2 still. diff --git a/gcc/testsuite/gfortran.dg/pr114618.f90 b/gcc/testsuite/gfortran.dg/pr114618.f90 new file mode 100644 index 000..835597b8513 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr114618.f90 @@ -0,0 +1,15 @@ +! { dg-do run } +! PR114618 Format produces incorrect output when contains 1x, ok when uses " " +! aside: Before patch output1 is garbage. +program pr114618 + implicit none + integer, parameter :: wp = kind(0d0) + real(kind=wp) :: pi = 3.14159265358979323846264338_wp + character(len=*), parameter:: fmt1 = '(19("."),t1,g0,1x,t21,g0)' + character(len=*), parameter:: fmt2 = '(19("."),t1,g0," ",t21,g0)' + character(21) :: output1, output2 + write (output1, fmt1) 'RADIX', radix(pi) + write (output2, fmt2) 'RADIX', radix(pi) + if (output1 /= 'RADIX.. 2') stop 1 + if (output2 /= 'RADIX . 2') stop 2 +end program pr114618 diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index b3b72f39c5b..3fc53938b4a 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -2068,12 +2068,14 @@ static void formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind, size_t size) { - gfc_offset pos, bytes_used; + gfc_offset tab_pos, bytes_used; const fnode *f; format_token t; int n; int consume_data_flag; + tab_pos = 0; bytes_used = 0; + /* Change a complex data item into a pair of reals. */ n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2); @@ -2398,10 +2400,12 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin case FMT_X: case FMT_TR: consume_data_flag = 0; - dtp->u.p.skips += f->u.n; - pos = bytes_used + dtp->u.p.skips - 1; - dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1; + tab_pos = bytes_used + dtp->u.p.skips - 1; + dtp->u.p.pending_spaces = tab_pos - dtp->u.p.max_pos + 1; + dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 +? f->u.n : dtp->u.p.pending_spaces; + /* Writes occur just before the switch on f->format, above, so that trailing blanks are suppressed, unless we are doing a non-advancing write in which case we want to output the blanks @@ -2414,35 +2418,50 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin break; case FMT_TL: - case FMT_T: consume_data_flag = 0; - - if (f->format == FMT_TL) + /* Handle the special case when no bytes have been used yet. + Cannot go below zero. */ + if (bytes_used == 0) { - - /* Handle the special case when no bytes have been used yet. - Cannot go below zero. */ - if (bytes_used == 0) - { - dtp->u.p.pending_spaces -= f->u.n; - dtp->u.p.skips -= f->u.n; - dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips; - } - - pos = bytes_used - f->u.n; + dtp->u.p.pending_spaces -= f->u.n; + dtp->u.p.skips -= f->u.n; + dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips; } - else /* FMT_T */ - pos = f->u.n - dtp->u.p.pending_spaces - 1; + + tab_pos = bytes_used - f->u.n; /* Standard 10.6.1.1: excessive left tabbing is reset to the left tab limit. We do not check if the position has gone beyond the end of
Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]
Committed as: commit e41a5a2a0832509fa1c0b7cab0c8001fadbd23d4 (HEAD -> master, origin/master, origin/HEAD) Author: Jerry DeLisle Date: Tue Feb 4 17:21:42 2025 -0800 Fortran: Fix PR 47485. The -MT and -MQ options should replace the default target in the generated dependency file. deps_add_target needs to be called before cpp_read_main_file, otherwise the original object name is added. Contributed by Vincent Vanlaer PR fortran/47485 gcc/fortran/ChangeLog: * cpp.cc: fix -MT/-MQ adding additional target instead of replacing the default. gcc/testsuite/ChangeLog: * gfortran.dg/dependency_generation_1.f90: New test. Signed-off-by: Vincent Vanlaer
Re: [PATCH] Fortran: host association issue with symbol in COMMON block [PR108454]
On 1/30/25 1:44 PM, Harald Anlauf wrote: Dear all, analyzing the the PR (by Gerhard) turned out to two slightly related issues. The first one, where a variable in a COMMON block is falsely resolved to a derived type declared in the host, leads to a false freeing of the symbol, resulting in memory corruption and ICE. If we already know that the symbol is in a common block, we may just skip that interface search. The other issue is a resolution issue, where the derived type declared in the host is used in a variable declaration in the procedure (as type or class), and a variable of the same name as the derived type is used in a common block but later resolves to a basic type, without a proper detection of the conflict. But as this issue is found to be independent of the presence of a COMMON block, I have opened a separate issue (pr118709) for it. Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Looks good to go Harald. As always, thanks for the fix. Jerry
Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]
On 2/4/25 9:29 AM, Jerry D wrote: On 2/3/25 4:46 PM, Vincent Vanlaer wrote: On 4/02/2025 01:42, Jerry D wrote: On 2/3/25 2:14 PM, Vincent Vanlaer wrote: Hi all, Gentle ping for the patch below: https://gcc.gnu.org/pipermail/ fortran/2024-December/061467.html Best wishes, Vincent On 30/12/2024 00:19, Vincent Vanlaer wrote: The -MT and -MQ options should replace the default target in the generated dependency file. deps_add_target needs to be called before cpp_read_main_file, otherwise the original object name is added. gcc/fortran/ PR fortran/47485 * cpp.cc: fix -MT/-MQ adding additional target instead of replacing the default gcc/testsuite/ PR fortran/47485 * gfortran.dg/dependency_generation_1.f90: New test Signed-off-by: Vincent Vanlaer --- gcc/fortran/cpp.cc | 18 +++ +-- .../gfortran.dg/dependency_generation_1.f90 | 15 +++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/ dependency_generation_1.f90 diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc index 7c5f00cfd69..3b93d17b90f 100644 --- a/gcc/fortran/cpp.cc +++ b/gcc/fortran/cpp.cc @@ -96,6 +96,8 @@ struct gfc_cpp_option_data int deps_skip_system; /* -MM */ const char *deps_filename; /* -M[M]D */ const char *deps_filename_user; /* -MF */ + const char *deps_target_filename; /* -MT / -MQ */ + bool quote_deps_target_filename; /* -MQ */ int deps_missing_are_generated; /* -MG */ int deps_phony; /* -MP */ int warn_date_time; /* -Wdate-time */ @@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int decoded_options_count, gfc_cpp_option.deps_missing_are_generated = 0; gfc_cpp_option.deps_filename = NULL; gfc_cpp_option.deps_filename_user = NULL; + gfc_cpp_option.deps_target_filename = NULL; + gfc_cpp_option.quote_deps_target_filename = false; gfc_cpp_option.multilib = NULL; gfc_cpp_option.prefix = NULL; @@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED case OPT_MQ: case OPT_MT: - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code; - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg; - gfc_cpp_option.deferred_opt_count++; + gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ); + gfc_cpp_option.deps_target_filename = arg; break; case OPT_P: @@ -593,6 +596,12 @@ gfc_cpp_init_0 (void) } gcc_assert(cpp_in); + + if (gfc_cpp_option.deps_target_filename) + if (mkdeps *deps = cpp_get_deps (cpp_in)) + deps_add_target (deps, gfc_cpp_option.deps_target_filename, + gfc_cpp_option.quote_deps_target_filename); + if (!cpp_read_main_file (cpp_in, gfc_source_file)) errorcount++; } @@ -635,9 +644,6 @@ gfc_cpp_init (void) else cpp_assert (cpp_in, opt->arg); } - else if (opt->code == OPT_MT || opt->code == OPT_MQ) - if (mkdeps *deps = cpp_get_deps (cpp_in)) - deps_add_target (deps, opt->arg, opt->code == OPT_MQ); } /* Pre-defined macros for non-required INTEGER kind types. */ diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 b/ gcc/testsuite/gfortran.dg/dependency_generation_1.f90 new file mode 100644 index 000..d42a257f83a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 @@ -0,0 +1,15 @@ +! This test case ensures that the -MT flag is correctly replacing the object name in the dependency file. +! See PR 47485 +! +! Contributed by Vincent Vanlaer +! +! { dg-do preprocess } +! { dg-additional-options "-cpp" } +! { dg-additional-options "-M" } +! { dg-additional-options "-MF deps" } +! { dg-additional-options "-MT obj.o" } + +module test +end module + +! { dg-final { scan-file "deps" "obj.o:.*" } } Do you have commit rights to gcc? I did not catch your original post. Jerry I do not, this is my first time contributing to GCC. Vincent This all looks reasonable to me. I will push this if no objections come in today. Regards, Jerry Regression tested OK. New test case passes. So far all is well. Standing by for any other comments. Jerry
Re: [PING, PATCH] fortran: fix -MT/-MQ adding additional target [PR47485]
On 2/3/25 4:46 PM, Vincent Vanlaer wrote: On 4/02/2025 01:42, Jerry D wrote: On 2/3/25 2:14 PM, Vincent Vanlaer wrote: Hi all, Gentle ping for the patch below: https://gcc.gnu.org/pipermail/ fortran/2024-December/061467.html Best wishes, Vincent On 30/12/2024 00:19, Vincent Vanlaer wrote: The -MT and -MQ options should replace the default target in the generated dependency file. deps_add_target needs to be called before cpp_read_main_file, otherwise the original object name is added. gcc/fortran/ PR fortran/47485 * cpp.cc: fix -MT/-MQ adding additional target instead of replacing the default gcc/testsuite/ PR fortran/47485 * gfortran.dg/dependency_generation_1.f90: New test Signed-off-by: Vincent Vanlaer --- gcc/fortran/cpp.cc | 18 +++ +-- .../gfortran.dg/dependency_generation_1.f90 | 15 +++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/ dependency_generation_1.f90 diff --git a/gcc/fortran/cpp.cc b/gcc/fortran/cpp.cc index 7c5f00cfd69..3b93d17b90f 100644 --- a/gcc/fortran/cpp.cc +++ b/gcc/fortran/cpp.cc @@ -96,6 +96,8 @@ struct gfc_cpp_option_data int deps_skip_system; /* -MM */ const char *deps_filename; /* -M[M]D */ const char *deps_filename_user; /* -MF */ + const char *deps_target_filename; /* -MT / -MQ */ + bool quote_deps_target_filename; /* -MQ */ int deps_missing_are_generated; /* -MG */ int deps_phony; /* -MP */ int warn_date_time; /* -Wdate-time */ @@ -287,6 +289,8 @@ gfc_cpp_init_options (unsigned int decoded_options_count, gfc_cpp_option.deps_missing_are_generated = 0; gfc_cpp_option.deps_filename = NULL; gfc_cpp_option.deps_filename_user = NULL; + gfc_cpp_option.deps_target_filename = NULL; + gfc_cpp_option.quote_deps_target_filename = false; gfc_cpp_option.multilib = NULL; gfc_cpp_option.prefix = NULL; @@ -439,9 +443,8 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED case OPT_MQ: case OPT_MT: - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code; - gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg; - gfc_cpp_option.deferred_opt_count++; + gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ); + gfc_cpp_option.deps_target_filename = arg; break; case OPT_P: @@ -593,6 +596,12 @@ gfc_cpp_init_0 (void) } gcc_assert(cpp_in); + + if (gfc_cpp_option.deps_target_filename) + if (mkdeps *deps = cpp_get_deps (cpp_in)) + deps_add_target (deps, gfc_cpp_option.deps_target_filename, + gfc_cpp_option.quote_deps_target_filename); + if (!cpp_read_main_file (cpp_in, gfc_source_file)) errorcount++; } @@ -635,9 +644,6 @@ gfc_cpp_init (void) else cpp_assert (cpp_in, opt->arg); } - else if (opt->code == OPT_MT || opt->code == OPT_MQ) - if (mkdeps *deps = cpp_get_deps (cpp_in)) - deps_add_target (deps, opt->arg, opt->code == OPT_MQ); } /* Pre-defined macros for non-required INTEGER kind types. */ diff --git a/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 b/ gcc/testsuite/gfortran.dg/dependency_generation_1.f90 new file mode 100644 index 000..d42a257f83a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_generation_1.f90 @@ -0,0 +1,15 @@ +! This test case ensures that the -MT flag is correctly replacing the object name in the dependency file. +! See PR 47485 +! +! Contributed by Vincent Vanlaer +! +! { dg-do preprocess } +! { dg-additional-options "-cpp" } +! { dg-additional-options "-M" } +! { dg-additional-options "-MF deps" } +! { dg-additional-options "-MT obj.o" } + +module test +end module + +! { dg-final { scan-file "deps" "obj.o:.*" } } Do you have commit rights to gcc? I did not catch your original post. Jerry I do not, this is my first time contributing to GCC. Vincent This all looks reasonable to me. I will push this if no objections come in today. Regards, Jerry
Re: [patch, libfortran] PR114618 Version 2 Format produces incorrect output when contains 1x, ok when uses " "
On 1/31/25 11:30 AM, Harald Anlauf wrote: --- snip -- So either commit the current version and track this issue in a PR if not yet done, or have a look if there is a quick fix. Thanks for the work! Harald Committed as: commit cfed99751c1a3b93ca66451eb1b62271e682f927 (HEAD -> master, origin/master, origin/HEAD) Author: Jerry DeLisle Date: Wed Jan 29 13:40:59 2025 -0800 Fortran: Fix handling of the X edit descriptor.
Re: [patch, libfortran] PR114618 Version 2 Format produces incorrect output when contains 1x, ok when uses " "
On 1/31/25 11:30 AM, Harald Anlauf wrote: Hi Jerry, Am 30.01.25 um 21:50 schrieb Jerry D: On 1/29/25 10:30 AM, Jerry D wrote: Follow-up: On 1/28/25 1:33 PM, Harald Anlauf wrote: Jerry, while I haven't read your actual patch yet, I think the testcase is slightly incorrect. In fact, Intel, NAG, Nvidia and AMD flang disagree with it. --- snip --- The following adjustment to the patch puts this right. case FMT_X: case FMT_TR: consume_data_flag = 0; dtp->u.p.skips += f->u.n; tab_pos = bytes_used + dtp->u.p.skips - 1; dtp->u.p.pending_spaces = tab_pos - dtp->u.p.max_pos + 1; dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? f->u.n : dtp->u.p.pending_spaces; //if (t == FMT_X && tab_pos < dtp->u.p.max_pos) //{ //write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces); //dtp->u.p.skips = dtp->u.p.pending_spaces = 0; //} Interestingly, it also fixes a floating point exception I ran into while setting up another test case for part 2 of this effort. I suspect this may be what was detected by the auto patch tester. I will clean this up, adjust the test case for this part and re-submit. Regards, Jerry Here is version 2 of the patch cleaned up and with the test case revised accordingly. Thank you Herald for helping with my blindness. Regressions tested on x86_64. I will wait a bit to see if the auto patch tester reports anything. Otherwise, OK for trunk? this looks mostly good. There is only one (minor?) issue I saw: writing output to a file, there is a discrepancy between stream- and non-stream I/O. Adding write (*, fmt1) 'RADIX', radix(pi) write (*, fmt2) 'RADIX', radix(pi) open (10, form="formatted") write(10, fmt1) 'RADIX', radix(pi) write(10, fmt2) 'RADIX', radix(pi) close(10) open (11, form="formatted", access="stream") write(11, fmt1) 'RADIX', radix(pi) write(11, fmt2) 'RADIX', radix(pi) close(11) shows agreement between stdout and fort.10, while fort.11 differs: % head fort.10 fort.11 ==> fort.10 <== RADIX.. 2 RADIX . 2 ==> fort.11 <== RADIX 2 RADIX 2... Other brands do not show this discrepancy. Regards, Jerry PS working on part 2 still. Are you addressing this in the second part of your work? As the test program crashes with current HEAD and earlier anyway, your patch is already progress, but we don't want to leave it that way. So either commit the current version and track this issue in a PR if not yet done, or have a look if there is a quick fix. Thanks for the work! Harald After studying this a bit more I will commit the subject patch. I have opened a new PR to track this. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118774 Regards, Jerry
Re: [PATCH] Fortran: different character lengths in array constructor [PR93289]
On 2/1/25 10:25 AM, Harald Anlauf wrote: Dear all, the attached patch downgrades different constant character lengths in an array constructor from a GNU to a legacy extension, so that users get a warning with -std=gnu. We continue to generate an error when standard conformance is requested. Regtested on x86_64-pc-linux-gnu (found one testcase where this triggered... :) OK for mainline? Thanks, Harald Yes, OK, and thanks Jerry
Re: [patch, libfortran] PR114618 Version 2 Format produces incorrect output when contains 1x, ok when uses " "
On 1/31/25 11:30 AM, Harald Anlauf wrote: Hi Jerry, Am 30.01.25 um 21:50 schrieb Jerry D: On 1/29/25 10:30 AM, Jerry D wrote: Follow-up: On 1/28/25 1:33 PM, Harald Anlauf wrote: Jerry, while I haven't read your actual patch yet, I think the testcase is slightly incorrect. In fact, Intel, NAG, Nvidia and AMD flang disagree with it. --- snip --- The following adjustment to the patch puts this right. case FMT_X: case FMT_TR: consume_data_flag = 0; dtp->u.p.skips += f->u.n; tab_pos = bytes_used + dtp->u.p.skips - 1; dtp->u.p.pending_spaces = tab_pos - dtp->u.p.max_pos + 1; dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? f->u.n : dtp->u.p.pending_spaces; //if (t == FMT_X && tab_pos < dtp->u.p.max_pos) //{ //write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces); //dtp->u.p.skips = dtp->u.p.pending_spaces = 0; //} Interestingly, it also fixes a floating point exception I ran into while setting up another test case for part 2 of this effort. I suspect this may be what was detected by the auto patch tester. I will clean this up, adjust the test case for this part and re-submit. Regards, Jerry Here is version 2 of the patch cleaned up and with the test case revised accordingly. Thank you Herald for helping with my blindness. Regressions tested on x86_64. I will wait a bit to see if the auto patch tester reports anything. Otherwise, OK for trunk? this looks mostly good. There is only one (minor?) issue I saw: writing output to a file, there is a discrepancy between stream- and non-stream I/O. Adding write (*, fmt1) 'RADIX', radix(pi) write (*, fmt2) 'RADIX', radix(pi) open (10, form="formatted") write(10, fmt1) 'RADIX', radix(pi) write(10, fmt2) 'RADIX', radix(pi) close(10) open (11, form="formatted", access="stream") write(11, fmt1) 'RADIX', radix(pi) write(11, fmt2) 'RADIX', radix(pi) close(11) shows agreement between stdout and fort.10, while fort.11 differs: % head fort.10 fort.11 ==> fort.10 <== RADIX.. 2 RADIX . 2 ==> fort.11 <== RADIX 2 RADIX 2... Other brands do not show this discrepancy. Regards, Jerry PS working on part 2 still. Are you addressing this in the second part of your work? Yes, part 2 which I am still working on. As the test program crashes with current HEAD and earlier anyway, your patch is already progress, but we don't want to leave it that way. So either commit the current version and track this issue in a PR if not yet done, or have a look if there is a quick fix. Thanks for the work! Harald To make sure I will add the example with 'stream' to an existing or new PR. I need to look to see what this is doing. I have not heard back from the arm auto-patch tester so I hope the patch here is an improvement. Thanks, Jerry
Re: [patch, libgfortran] Bug 117819 - Formatted READ with BZ in format fails
Pushed r15-6090-gcf406a6c Thanks for the review! Jerry On 12/10/24 12:15 AM, Andre Vehreschild wrote: Hi Jerry, patch looks good. Ok for mainline and backport after grace period. Thanks for the patch, Andre On Mon, 9 Dec 2024 20:31:08 -0800 Jerry D wrote: Hi all, The attached patch fixes this bug by checking for the case of a short READ that should be padded with blanks and if the BZ mode is enabled, those blanks should be treated as trailing zero's. New test case courtesy Malcom Cohen. Regression tested on X86_64_linux_gnu. OK for trunk and backport to 14 in a few days. uthor: Jerry DeLisle Date: Mon Dec 9 20:11:23 2024 -0800 Fortran: Fix READ with padding in BLANK ZERO mode. PR fortran/117819 libgfortran/ChangeLog: * io/read.c (read_decimal): If the read value is short of the specified width and pad mode is PAD yes, check for BLANK ZERO and adjust the value accordingly. (read_decimal_unsigned): Likewise. (read_radix): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/pr117819.f90: New test. -- Andre Vehreschild * Email: vehre ad gmx dot de
[patch, libgfortran] Bug 117819 - Formatted READ with BZ in format fails
Hi all, The attached patch fixes this bug by checking for the case of a short READ that should be padded with blanks and if the BZ mode is enabled, those blanks should be treated as trailing zero's. New test case courtesy Malcom Cohen. Regression tested on X86_64_linux_gnu. OK for trunk and backport to 14 in a few days. uthor: Jerry DeLisle Date: Mon Dec 9 20:11:23 2024 -0800 Fortran: Fix READ with padding in BLANK ZERO mode. PR fortran/117819 libgfortran/ChangeLog: * io/read.c (read_decimal): If the read value is short of the specified width and pad mode is PAD yes, check for BLANK ZERO and adjust the value accordingly. (read_decimal_unsigned): Likewise. (read_radix): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/pr117819.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr117819.f90 b/gcc/testsuite/gfortran.dg/pr117819.f90 new file mode 100644 index 000..d9a9b7f6f9b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr117819.f90 @@ -0,0 +1,45 @@ +! { dg-do run } +! PR117819 +Program xe1 + Implicit None + Character(6) string + Integer x + Logical :: ok = .True. + string = '11' + !print *, "String we read from is: ", string + Read(string,1) x +1 Format(BZ,B8) + If (x/=Int(b'1100')) Then +Print *,'FAIL B8 BZ wrong result' +Print *,'Expected',Int(b'1100') +Print *,'Received',x +ok = .False. + End If + string = '123456' + !print *, "String we read from is: ", string + Read(string,2) x +2 Format(BZ,I8) + If (x/=12345600) Then +Print *,'FAIL I8 BZ wrong result' +Print *,'Expected',12345600 +Print *,'Received',x +ok = .False. + End If + Read(string,3) x +3 Format(BZ,O8) + If (x/=Int(o'12345600')) Then +Print *,'FAIL O8 BZ wrong result' +Print *,'Expected',Int(o'12345600') +Print *,'Received',x +ok = .False. + End If + Read(string,4) x +4 Format(BZ,Z8) + If (x/=Int(z'12345600')) Then +Print *,'FAIL OZ BZ wrong result' +Print *,'Expected',Int(z'12345600') +Print *,'Received',x +ok = .False. + End If + If (.not. ok) stop 1 +End Program diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index aa866bf31da..46413ade001 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -753,11 +753,11 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { GFC_UINTEGER_LARGEST value, maxv, maxv_10; GFC_INTEGER_LARGEST v; - size_t w; + size_t w, padding; int negative; char c, *p; - w = f->u.w; + w = padding = f->u.w; /* This is a legacy extension, and the frontend will only allow such cases * through when -fdec-format-defaults is passed. @@ -770,6 +770,10 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) if (p == NULL) return; + /* If the read was not the full width we may need to pad with blanks or zeros + * depending on the PAD mode. Save the number of pad characters needed. */ + padding -= w; + p = eat_leading_spaces (&w, p); if (w == 0) { @@ -807,7 +811,14 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { c = next_char (dtp, &p, &w); if (c == '\0') - break; + { + if (dtp->u.p.blank_status == BLANK_ZERO) + { + for (size_t n = 0; n < padding; n++) + value = 10 * value; + } + break; + } if (c == ' ') { @@ -864,11 +875,11 @@ read_decimal_unsigned (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { GFC_UINTEGER_LARGEST value, old_value; - size_t w; + size_t w, padding; int negative; char c, *p; - w = f->u.w; + w = padding = f->u.w; /* This is a legacy extension, and the frontend will only allow such cases * through when -fdec-format-defaults is passed. @@ -881,6 +892,10 @@ read_decimal_unsigned (st_parameter_dt *dtp, const fnode *f, char *dest, if (p == NULL) return; + /* If the read was not the full width we may need to pad with blanks or zeros + * depending on the PAD mode. Save the number of pad characters needed. */ + padding -= w; + p = eat_leading_spaces (&w, p); if (w == 0) { @@ -917,7 +932,14 @@ read_decimal_unsigned (st_parameter_dt *dtp, const fnode *f, char *dest, { c = next_char (dtp, &p, &w); if (c == '\0') - break; + { + if (dtp->u.p.blank_status == BLANK_ZERO) + { + for (size_t n = 0; n < padding; n++) + value = 10 * value; + } + break; + } if (c == ' ') { @@ -981,17 +1003,21 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, { GFC_UINTEGER_LARGEST value, maxv, maxv_r; GFC_INTEGER_LARGEST v; - size_t w; + size_t w, padding; int negative; char c, *p; - w = f->u.w; + w = padding = f->u.w; p = read_block_form (dtp, &w); if (p == NULL) return; + /* If the read was not the full width we may need to pad with blanks or zeros + * depending on the PAD mode. Save the
Re: [Fortran, Patch, PR117643] Implement F_C_STRING()
On 12/18/24 4:11 AM, Harald Anlauf wrote: Hi Steve, thanks for the draft patch. I haven't looked close enough, but you may have to add support for 'asis' being an optional dummy variable. The following example crashes here with a segfault: program foo use iso_c_binding, only : c_null_char, c_char, f_c_string, c_size_t implicit none logical asis character(len=6, kind=c_char) :: s1 character(len=:, kind=c_char), allocatable :: s2 interface ! ! strlen() counts up to '\0', and excludes it from the count ! function strlen(s) bind(c,name="strlen") import c_char, c_size_t integer(c_size_t) strlen character(len=1,kind=c_char), intent(in) :: s(*) end function strlen end interface s1 = 'abc ' asis = .true. call check (asis) ! OK asis = .false. call check (asis) ! OK call check () ! segfault contains subroutine check (asis) logical, optional, intent(in) :: asis s2 = f_c_string(s1, asis) print *, len_trim(s1), int(strlen(s2)) end subroutine check end program foo --- snip --- This is interesting. In my tests I tried: print *, len(s1), len(f_c_string(s1)) Which works fine. Is the user required to check for the presence of the optional argument before using it? From the 'view' of the subroutine 'asis' exists but is undefined. Regards, Jerry
Re: [PING!, Fortran, Patch, PR107635, Part 1] Rework handling of allocatable components in derived type coarrays.
Andre, have you tested this with the tests in OpenCoarrays suite? I ask since this touches coarray things. Jerry On 12/16/24 1:58 AM, Andre Vehreschild wrote: PING! On Fri, 6 Dec 2024 19:10:08 +0100 Andre Vehreschild wrote: Hi all, I had to dive deeply into the issue with handling allocatable components in derived types and to find a future proof solution. I hope do have found a universal and flexible one now: For each allocatable (or pointer) component in a derived type a coarray token is required. While this is quite easy for the current compilation unit, it is very difficult to do for arbitrary compilation units or when one gets libraries that are not aware of coarray's needs. The approach this patch now implements is to delegate the evaluation of a reference into a coarray into a separate access routine. This routine is present on every image, because it is generated by the compiler at the time it knows that a coarray access is done. With external compilation units or libraries this solves the access issue, because each image knows how to access its own objects, but does not need a coarray token for allocatable (or pointer) components anymore. The access on the remote image's object is done by the remote image itself (for the MPI implementation in a separate thread). Therefore it knows about the bounds of arrays, allocation and association state of components and can handle those. Furthermore is this approach faster, because it has O(1) complexity regarding the communication. The old approach was O(N) where N is the number of allocatable/pointer components + array descriptors on the path of the access. The new approach sends a set of parameters to the remote image and gets the desired data in return. At the moment the patch handles only getting of data from a remote image. It is split into two patchsets. The first one does some preparatory clean up, like stopping to add caf_get calls into the expression tree and removing them afterwards again, where they are in the way. The second patch is then doing the access routine creation. Unfortunately is this the longer patch. I have also updated the documentation of the caf API. I hope to not have overlooked something. This is the first part of a series to rework all coarray access routines to use the new approach and then remove the deprecated calls. This makes things clearer and easier to maintain, although the tree-dump now presents some more generated routines, which might look odd. Bootstrapped and regtested ok on x86_64-pc-linux-gnu / Fedora 39 and 41. Ok for mainline? I will continue working on the coarray stuff and fix upcoming bugs in the future. Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de -- Andre Vehreschild * Email: vehre ad gmx dot de
Re: [PATCH] Fortran: potential aliasing of complex pointer inquiry references [PR118120]
On 12/19/24 1:34 PM, Harald Anlauf wrote: Dear all, the check for potential aliasing of lhs and rhs currently shortcuts if the types differ. This is a problem if one is of type complex and the other is of type real (and of the same kind parameter value), as this ignores that F2008 inquiry references (%RE, %IM) could be involved. The attached patch just addresses this shortcut. This may not be a complete solution, see discussion in the PR, but is a lightweight solution (for the time being). Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald I agree with Steve, OK. The inquiry references can be dealt with later. Regards, Jerry
Re: [Fortran, Patch, PR57598] Fix coarray STOP
On 12/19/24 4:13 AM, Andre Vehreschild wrote: Hi all, attached patch fixes a rather old open issue, that I stumbled upon while trying to figure, why a test failed on the command line but not in the testsuite. The implementation of the STOP command in caf_single did not hand the errorcode over to the OS, as does non-caf STOP and as it is required by the standard. So I fixed that. I also added reporting of exceptions to the coarray (ERROR)? STOP routines. For this I have exported the existing function of the regular gfortran runtime library. I tried to do this via iexport_proto, but was never able to access the routine from the caf-library. I always got linker errors. After fixing caf-STOP the testsuite reported one regression, which I also fixed in send_by_ref. Bootstrapped and regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline? Regards, Andre -- Andre Vehreschild * Email: vehre ad gcc dot gnu dot org Yes, this is OK. Thanks, Jerry
[libgfortran, patch] PR88052 Format contravening constraint C1002 permitted
Hi all, I had originally created this patch in 2018 and we did not get back to it. This results in more restrictive runtime behavior. I will go through the front-end code with another patch to catch this at compile time. Changelog and new test case. See attached patch. OK for trunk Author: Jerry DeLisle Date: Fri Nov 22 19:29:42 2024 -0800 Fortran: Reject missing comma in format. Standards require rejecting formats where descriptors are not separated by commas. This change allows this the missing comma to be accepted only with -std=legacy. PR fortran/88052 libgfortran/ChangeLog: * io/format.c (parse_format_list): Reject missing comma in format strings by default or if -std=f95 or higher. This is a runtime error. gcc/testsuite/ChangeLog: * gfortran.dg/comma_format_extension_4.f: Add missing comma. * gfortran.dg/dollar_edit_descriptor_2.f: Likewise. * gfortran.dg/fmt_error_9.f: Likewise. * gfortran.dg/fmt_g0_5.f08: Likewise. * gfortran.dg/fmt_t_2.f90: Likewise. * gfortran.dg/pr88052.f90: New test.diff --git a/gcc/testsuite/gfortran.dg/comma_format_extension_4.f b/gcc/testsuite/gfortran.dg/comma_format_extension_4.f index 30f07e803c5..1d018380f9c 100644 --- a/gcc/testsuite/gfortran.dg/comma_format_extension_4.f +++ b/gcc/testsuite/gfortran.dg/comma_format_extension_4.f @@ -1,7 +1,7 @@ ! PR fortran/13257 -! Note the missing , before i1 in the format. +! Note the missing , after i4 in the format. ! { dg-do run } -! { dg-options "" } +! { dg-options "-std=legacy" } character*6 c write (c,1001) 1 if (c .ne. '1 ') STOP 1 diff --git a/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f b/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f index 437f4dfd811..de583f374dc 100644 --- a/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f +++ b/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-options "-w" } +! { dg-options "-w -std=legacy" } ! PR25545 internal file and dollar edit descriptor. program main character*20 line diff --git a/gcc/testsuite/gfortran.dg/fmt_error_9.f b/gcc/testsuite/gfortran.dg/fmt_error_9.f index 40c73599ac8..2755074054c 100644 --- a/gcc/testsuite/gfortran.dg/fmt_error_9.f +++ b/gcc/testsuite/gfortran.dg/fmt_error_9.f @@ -4,7 +4,7 @@ ! Test case prepared by Jerry DeLisle character(len=25) :: str character(len=132) :: msg, line - str = '(1pd24.15e6)' + str = '(1pd24.15,e6)' line = "initial string" x = 555.25 @@ -19,11 +19,11 @@ if (istat.ne.5006 .or. msg(1:10).ne."Zero width") STOP 4 if (x.ne.555.25) STOP 5 - write (line,'(1pd24.15e11.3)') 1.0d0, 1.234 + write (line,'(1pd24.15,e11.3)') 1.0d0, 1.234 if (line.ne." 1.000D+00 1.234E+00") STOP 6 str = '(1p2d24.15)' msg = " 1.000D+00 1.23367575073D+00That's it!" - write (line,'(1p2d24.15a)') 1.0d0, 1.234, "That's it!" + write (line,'(1p2d24.15,a)') 1.0d0, 1.234, "That's it!" if (line.ne.msg) print *, msg end diff --git a/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 b/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 index d2a97b1ac80..cafd90b94b5 100644 --- a/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 +++ b/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 @@ -6,13 +6,13 @@ program test_g0_special call check_all("(g10.3)", "(f10.3)") call check_all("(g10.3e3)", "(f10.3)") -call check_all("(spg10.3)", "(spf10.3)") -call check_all("(spg10.3e3)", "(spf10.3)") +call check_all("(sp,g10.3)", "(sp,f10.3)") +call check_all("(sp,g10.3e3)", "(sp,f10.3)") !print *, "---" call check_all("(g0)", "(f0.0)") call check_all("(g0.15)", "(f0.0)") -call check_all("(spg0)", "(spf0.0)") -call check_all("(spg0.15)", "(spf0.0)") +call check_all("(sp,g0)", "(sp,f0.0)") +call check_all("(sp,g0.15)", "(sp,f0.0)") contains subroutine check_all(fmt1, fmt2) character(len=*), intent(in) :: fmt1, fmt2 diff --git a/gcc/testsuite/gfortran.dg/fmt_t_2.f90 b/gcc/testsuite/gfortran.dg/fmt_t_2.f90 index 01647655de6..56414c54bfb 100644 --- a/gcc/testsuite/gfortran.dg/fmt_t_2.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_t_2.f90 @@ -12,7 +12,7 @@ read (11, '(a040,t1,040a)', end = 999) foost1 , foost2 if (foost1.ne.foost2) STOP 1 - read (11, '(a032,t2,a032t3,a032)', end = 999) foost1 , foost2, foost3 + read (11, '(a032,t2,a032,t3,a032)', end = 999) foost1 , foost2, foost3 if (foost1(1:32).ne."123456789 123456789 123456789 ") STOP 2 if (foost2(1:32).ne."23456789 123456789 123456789") STOP 3 if (foost3(1:32).ne."3456789 123456789 123456789 ") STOP 4 diff --git a/gcc/testsuite/gfortran.dg/pr88052.f90 b/gcc/testsuite/gfortra
Re: [libgfortran, patch] PR88052 Format contravening constraint C1002 permitted
On 11/23/24 12:40 AM, Thomas Koenig wrote: Hi Jerry, I had originally created this patch in 2018 and we did not get back to it. This results in more restrictive runtime behavior. I will go through the front-end code with another patch to catch this at compile time. Changelog and new test case. See attached patch. OK for trunk Yes, OK. Can you also make a mention of this in https://gcc.gnu.org/gcc-15/changes.html ? Best regards Thomas Thanks for review, pushed. Working on the docs change now. Jerry
Re: [2nd PING, Fortran, Patch, PR107635, Part 1] Rework handling of allocatable components in derived type coarrays.
On 12/20/24 9:09 AM, Andre Vehreschild wrote: Thank you very much Jerry. The delta between the two patches is really minor. In resolve.c I have removed some attr.pointer setting and in caf/single.c the handling for those as well as treating non-descriptor arrays differently. Most changes in the diff of v2 to v3 are about lines having moved due to other patches. And I will be around for fixing occurring issues. Btw, in the OpenCoarrays GitHub repo the branch for 774 implements this new way of accessing data for mpi. Thanks again for looking and regards, Andre Andre Vehreschild Please go ahead and Push. We have had some off list discussions and this is the best path forward. Best regards to all, Jerry
Re: [PATCH] Fortran: Added support for locality specs in DO CONCURRENT (Fortran 2018/23)
On 1/7/25 12:06 PM, Jerry D wrote: On 9/25/24 3:18 AM, Andre Vehreschild wrote: Hi all, I finally managed to apply the fixed patch. It still had some stray line break so check_GNU_style.py wouldn't succeed. But with that fixed I agree to have only some nonsense bickering of the script. As to the patch (I have stripped large parts.): diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 36ed8eeac2d..c6aefb81a73 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3042,6 +3042,16 @@ enum gfc_exec_op EXEC_OMP_ERROR, EXEC_OMP_ALLOCATE, EXEC_OMP_ALLOCATORS }; +/* Enum Definition for locality types. */ +enum locality_type +{ + LOCALITY_LOCAL = 0, + LOCALITY_LOCAL_INIT, + LOCALITY_SHARED, + LOCALITY_REDUCE, + LOCALITY_NUM +}; + typedef struct gfc_code { gfc_exec_op op; @@ -3089,7 +3099,15 @@ typedef struct gfc_code gfc_inquire *inquire; gfc_wait *wait; gfc_dt *dt; - gfc_forall_iterator *forall_iterator; + + struct + { + gfc_forall_iterator *forall_iterator; + gfc_expr_list *locality[LOCALITY_NUM]; + bool default_none; + } + concur; I am more than unhappy about that construct. Because every concurrent loop has a forall_iterator, but not every forall_iterator is a concurrent loop. I therefore propose to move the forall_iterator out of the struct and only have the concurrent specific elements in the struct. This would also reduce the changes significantly. Interestingly, simply moving the gfc_forall_iterator back to where it was before and changing all references to it to point to it I get a clean build of gfortran, but several of the testcases now fail with a segfault. For example: $ gfc -fcoarray=single do_concurrent_constraints.f90 f951: internal compiler error: Segmentation fault 0x22b9041 internal_error(char const*, ...) ../../trunk/gcc/diagnostic-global-context.cc:517 0xde4d6f crash_signal ../../trunk/gcc/toplev.cc:322 0x7053db parse_do_block ../../trunk/gcc/fortran/parse.cc:5414 0x7033c4 parse_executable ../../trunk/gcc/fortran/parse.cc:6396 0x7047ae parse_progunit ../../trunk/gcc/fortran/parse.cc:6803 0x704b58 parse_contained ../../trunk/gcc/fortran/parse.cc:6678 0x705b5c parse_module ../../trunk/gcc/fortran/parse.cc:7049 0x705f8c gfc_parse_file() ../../trunk/gcc/fortran/parse.cc:7351 0x75f69f gfc_be_parse_file ../../trunk/gcc/fortran/f95-lang.cc:241 In gdb it looks like the 'next' field in the iterator is pointing to garbage when it ought to be NULL. I am looking around to see why that is not getting initialized correctly or maybe this has uncovered something more nasty. Jerry The attached patch is the latest clean build and test run I can come up with. I completely cannot understand why moving the forall_iterator from the sub-structure 'concur' back to where it was at the 'ext' sub-structure of typedef struct gfc_code. 'ext' is a union. I suspected there is an overlap going on there such that something is getting overwritten or optimized away. I am unable to find the culprit. Regression tested on x86_64. OK for trunk? I will make sure the Changelog stuff is squared away. I also think I will open a PR regarding the problem I described above. Regards, Jerrydiff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 8d31ddfcffb..e97693d54d9 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -2899,7 +2899,7 @@ show_code_node (int level, gfc_code *c) case EXEC_FORALL: fputs ("FORALL ", dumpfile); - for (fa = c->ext.forall_iterator; fa; fa = fa->next) + for (fa = c->ext.concur.forall_iterator; fa; fa = fa->next) { show_expr (fa->var); fputc (' ', dumpfile); @@ -2959,7 +2959,7 @@ show_code_node (int level, gfc_code *c) case EXEC_DO_CONCURRENT: fputs ("DO CONCURRENT ", dumpfile); - for (fa = c->ext.forall_iterator; fa; fa = fa->next) + for (fa = c->ext.concur.forall_iterator; fa; fa = fa->next) { show_expr (fa->var); fputc (' ', dumpfile); @@ -2972,7 +2972,114 @@ show_code_node (int level, gfc_code *c) if (fa->next != NULL) fputc (',', dumpfile); } - show_expr (c->expr1); + + if (c->expr1 != NULL) + { + fputc (',', dumpfile); + show_expr (c->expr1); + } + + if (c->ext.concur.locality[LOCALITY_LOCAL]) + { + fputs (" LOCAL (", dumpfile); + + for (gfc_expr_list *el = c->ext.concur.locality[LOCALITY_LOCAL]; + el; el = el->next) + { + show_expr (el->expr); + if (el->next) + fputc (',', dumpfile); + } + fputc (')', dumpfile); + } + + if (c->ext.concur.locality[LOCALITY_LOCAL_INIT]) + { + fputs (&q