From: Jerry D <jvdelisle2@gmail.com>
To: Tobias Burnus <tburnus@baylibre.com>, gfortran <fortran@gcc.gnu.org>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>, Jerry D <jvdelisle2@gmail.com>
Subject: Re: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'"
Date: Thu, 4 Apr 2024 14:04:21 -0700 [thread overview]
Message-ID: <fc16074e-45f0-46f2-a7f5-735d49801a48@gmail.com> (raw)
In-Reply-To: <b4e78a90-40bc-421f-811e-fe446ab0772c@baylibre.com>
[-- Attachment #1: Type: text/plain, Size: 1427 bytes --]
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.00000000 ios= 0
> point, isreal = T , testinput = "3.3;"r= 3.29999995 ios= 0
> point, isreal = T , testinput = "3,3;"r= 3.00000000 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
[-- Attachment #2: submit2.diff --]
[-- Type: text/x-patch, Size: 7455 bytes --]
commit 9c8318cd8703d49ad7563e89765f8849ebc14385
Author: Jerry DeLisle <jvdelisle@gcc.gnu.org>
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 00000000000..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', '9 ;', .true.) ! No error shown
+ call t(.false., 'comma', '3,3.', .true.) ! Error shown
+ call t(.false., 'point', '3.3.', .true.) ! Error shown
+ call t(.false., 'comma', '3,3,', .true.) ! gfortran/flang: no error; ifort: error
+ call t(.true., 'comma', '3,3;', .true.) ! No error shown
+ call t(.false., 'point', '3.3;', .true.) ! gfortran/flang: no error; ifort: error
+ call t(.true., 'comma', '4,4 .', .true.) ! N error shown
+ call t(.true., 'point', '4.4 .', .true.) ! No error shown
+ call t(.true., 'comma', '4,4 ,', .true.) ! /!\ gfortran: error; others: no error
+ call t(.true., 'point', '4.4 ,', .true.) ! No error shown
+ call t(.true., 'comma', '4,4 ;', .true.) ! No error shown
+ call t(.true., 'point', '4.4 ;', .true.) ! No error shown
+
+! print *, '---------------'
+
+ call t(.true., 'comma', '8', .true.)
+ call t(.true., 'point', '8', .true.)
+ call t(.true., 'point', '9 ;', .true.)
+ call t(.true., 'comma', '3;3.', .true.)
+ call t(.true., 'point', '3,3.', .true.)
+ call t(.true., 'comma', '3;3,', .true.)
+ call t(.true., 'comma', '3;3;', .true.)
+ call t(.true., 'point', '3,3;', .true.)
+ call t(.true., 'comma', '4;4 .', .true.)
+ call t(.true., 'point', '4,4 .', .true.)
+ call t(.true., 'comma', '4;4 ,', .true.)
+ call t(.true., 'point', '4,4 ,', .true.)
+ call t(.true., 'comma', '4;4 ;', .true.)
+ call t(.true., 'point', '4,4 ;', .true.)
+contains
+subroutine t(valid, dec, testinput, isreal)
+ logical, value :: valid
+ character(len=*) :: dec, testinput
+ logical, optional :: isreal
+ logical :: isreal2
+ integer n,ios
+ real :: r
+ r = 42; n = 42
+ isreal2 = .false.
+ if (present(isreal)) isreal2 = isreal
+
+ if (isreal2) then
+ read(testinput,*,decimal=dec,iostat=ios) r
+ if ((valid .and. ios /= 0) .or. (.not.valid .and. ios == 0)) then
+ print '(*(g0))', valid, ', ', dec,', isreal = ',isreal2,', testinput = "',testinput,'"',', r=',r,' ios=',ios
+ print *, 'ERROR'
+ stop 1
+ end if
+ else
+ read(testinput,*,decimal=dec,iostat=ios) n
+ if ((valid .and. ios /= 0) .or. (.not.valid .and. ios == 0)) then
+ print '(*(g0))', valid, ', ', dec,', isreal = ',isreal2,', testinput = "',testinput,'"',', n=',n,' ios=',ios
+ print *, 'ERROR'
+ stop 1
+ end if
+ end if
+end
+end program
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index fb3f7dbc34d..6bf59329add 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,8 +495,18 @@ eat_separator (st_parameter_dt *dtp)
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;
next prev parent reply other threads:[~2024-04-04 21:04 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-04 1:33 Jerry D
2024-04-04 8:17 ` Paul Richard Thomas
2024-04-04 9:31 ` Tobias Burnus
2024-04-04 20:05 ` Jerry D
2024-04-04 21:04 ` Jerry D [this message]
2024-04-04 21:41 ` Tobias Burnus
2024-04-05 17:47 ` Jerry D
2024-04-06 2:38 ` Jerry D
2024-04-06 5:17 ` Tobias Burnus
2024-04-08 9:53 ` [Patch] Fortran: List-directed read - accept again tab as alternative to space as separator [PR114304] (was: [patch, libgfortran] PR114304 - [13/14 Regression] libgfortran I/O – bogus "Semicolon not allowed as separator with DECIMAL='point'") Tobias Burnus
2024-04-08 18:21 ` [Patch] Fortran: List-directed read - accept again tab as alternative to space as separator [PR114304] Jerry D
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fc16074e-45f0-46f2-a7f5-735d49801a48@gmail.com \
--to=jvdelisle2@gmail.com \
--cc=fortran@gcc.gnu.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=tburnus@baylibre.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).