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 -
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 3/6/24 9:13 AM, Harald Anlauf wrote: "The users message containing % and %% and %s and other stuff" I see what you mean. our standard error messages are expecting values in these places and since none are there, fault. Should we simply output "The users message containing % and %% and %s and other stuff" literally? Does intel allow inserting things like error locus in these message strings? 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 I do not have the intel compiler. I will look at this but I do not know what the expectation is. Is there non-standard treatment of % symbols? Jerry
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
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 On 3/6/24 05:06, Jerry D wrote: 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 (>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 Tue, Mar 05, 2024 at 08:06:10PM -0800, Jerry D wrote: > 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 > string_len_trim substracts 1 from the passed in argument. gfc_charlen_type string_len_trim (gfc_charlen_type len, const CHARTYPE *s) { if (len <= 0) return 0; const size_t long_len = sizeof (unsigned long); size_t i = len - 1; Does this account for the NULL? -- steve
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 (>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
Hi Jerry, on further thought, do we sanitize 'child_iomsg'? We pass it to snprintf as format. Wouldn't a strncpy be sufficient? Harald 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 (>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
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 (>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 5 March 2024 04:15:12 CET, Jerry D wrote: > >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? LGTM. thanks!
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_formatted +generic ::
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 29 February 2024 23:28:44 CET, Jerry D wrote: >On 2/29/24 12:56 PM, Steve Kargl wrote: >> On Thu, Feb 29, 2024 at 10:28:19AM -0800, 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. It was system dependent. In the lib, here, it was probed at runtime, cross used IOV_MAX on lunix per default, in the non error case looped. >PS I wish my mail client would not wrap text on me, working on that issue. try :paste Or set tw=0, although 80 makes sense for me, or 72 in mail (if you are able to clip)
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On 2/29/24 12:56 PM, Steve Kargl wrote: On Thu, Feb 29, 2024 at 10:28:19AM -0800, 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? If I look at the interfaces for UDTIO in F2023 (pp. 254-255), the declaration for iomsg is CHARACTER (LEN=*), INTENT(INOUT) :: iomsg F2023 (p. 62) has An asterisk as a type-param-value specifies that a length type parameter is an assumed type parameter. It is used for a dummy argument to assume the type parameter value from the effective argument, ... So, in theory, one should be able to get the required length from length from the argument. CHARACTER(LEN=23) str WRITE(6,'(DT)',iomsg=str) derived-type-entity If the subroutine supplied by the user internally creates an error message with 300 characters, then from the above I would think that it will be truncated to 23 characters. OTOH, if the user is expecting the full 300 characters with CHARACTER(LEN=300) str WRITE(6,'(DT)',iomsg=str) derived-type-entity then truncating internally to 256 seems wrong. Now, that I looked at the interface more closely, the declaration CHARACTER (LEN=*), INTENT(INOUT) :: iomsg seems to block the use of an unallocated deferred-length 'str' and (re)-allocation does not occur. Without addressing the length discussions above, I did find an existing function in libgfortran to trim the spaces at the end (string_len_trim). I am using it as follows: if ((dtp->u.p.child_saved_iostat != 0) && !(dtp->common.flags & IOPARM_HAS_IOMSG) && !(dtp->common.flags & IOPARM_HAS_IOSTAT)) { char message[IOMSG_LEN]; child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg) + 1; snprintf (message, child_iomsg_len, child_iomsg); generate_error (>common, dtp->u.p.child_saved_iostat, message); goto nml_err_ret; } I will study the len questions further. Jerry PS I wish my mail client would not wrap text on me, working on that issue.
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
On Thu, Feb 29, 2024 at 10:28:19AM -0800, 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? > If I look at the interfaces for UDTIO in F2023 (pp. 254-255), the declaration for iomsg is CHARACTER (LEN=*), INTENT(INOUT) :: iomsg F2023 (p. 62) has An asterisk as a type-param-value specifies that a length type parameter is an assumed type parameter. It is used for a dummy argument to assume the type parameter value from the effective argument, ... So, in theory, one should be able to get the required length from length from the argument. CHARACTER(LEN=23) str WRITE(6,'(DT)',iomsg=str) derived-type-entity If the subroutine supplied by the user internally creates an error message with 300 characters, then from the above I would think that it will be truncated to 23 characters. OTOH, if the user is expecting the full 300 characters with CHARACTER(LEN=300) str WRITE(6,'(DT)',iomsg=str) derived-type-entity then truncating internally to 256 seems wrong. Now, that I looked at the interface more closely, the declaration CHARACTER (LEN=*), INTENT(INOUT) :: iomsg seems to block the use of an unallocated deferred-length 'str' and (re)-allocation does not occur. -- Steve
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
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? Jerry
Re: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
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 -- Steve
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: [patch, libgfortran] Part 2: PR105456 Child I/O does not propage iostat
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 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()? 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? thanks! > > 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.