public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fortran: detect blanks within literal constants in free-form mode [PR92805]
@ 2022-07-28 20:11 Harald Anlauf
  2022-07-29 11:11 ` Mikael Morin
  0 siblings, 1 reply; 15+ messages in thread
From: Harald Anlauf @ 2022-07-28 20:11 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 381 bytes --]

Dear all,

in free-form mode, blanks are significant, so they cannot appear
in literal constants, especially not before or after the "_" that
separates the literal and the kind specifier.

The initial patch from Steve addressed numerical literals, which
I completed by adjusting the parsing of string literals.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Fortran-detect-blanks-within-literal-constants-in-fr.patch --]
[-- Type: text/x-patch, Size: 4603 bytes --]

From f58c00f5792d6ec0037696df733857580a029ba9 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* primary.cc (get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/primary.cc                        | 18 ++++++++++++--
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 3 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..9d200cdf65b 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -92,14 +92,21 @@ get_kind (int *is_iso_c)
 {
   int kind;
   match m;
+  char c;

   *is_iso_c = 0;

+  c = gfc_peek_ascii_char ();
+  if (gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+    return -2;
+
   if (gfc_match_char ('_') != MATCH_YES)
     return -2;

-  m = match_kind_param (&kind, is_iso_c);
-  if (m == MATCH_NO)
+  m = MATCH_NO;
+  c = gfc_peek_ascii_char ();
+  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
     gfc_error ("Missing kind-parameter at %C");

   return (m == MATCH_YES) ? kind : -1;
@@ -1074,6 +1081,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }

+  if (gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+    goto no_match;
+
   if (c == ' ')
     {
       gfc_gobble_whitespace ();
@@ -1083,6 +1093,10 @@ match_string_constant (gfc_expr **result)
   if (c != '_')
     goto no_match;

+  c = gfc_peek_ascii_char ();
+  if (gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+    goto no_match;
+
   gfc_gobble_whitespace ();

   c = gfc_next_char ();
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
--
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-28 20:11 [PATCH] Fortran: detect blanks within literal constants in free-form mode [PR92805] Harald Anlauf
@ 2022-07-29 11:11 ` Mikael Morin
  2022-07-29 19:59   ` [PATCH, v2] " Harald Anlauf
  0 siblings, 1 reply; 15+ messages in thread
From: Mikael Morin @ 2022-07-29 11:11 UTC (permalink / raw)
  To: Harald Anlauf, fortran, gcc-patches

Hello,

Le 28/07/2022 à 22:11, Harald Anlauf via Fortran a écrit :
> Dear all,
> 
> in free-form mode, blanks are significant, so they cannot appear
> in literal constants, especially not before or after the "_" that
> separates the literal and the kind specifier.
> 
> The initial patch from Steve addressed numerical literals, which
> I completed by adjusting the parsing of string literals.
> 
> Regtested on x86_64-pc-linux-gnu.  OK for mainline?
> 
It looks correct, but I think we should continue to have the free vs 
fixed form abstracted away from the parsing code.
So, I suggest instead to remove the calls to gfc_gobble_whitespace in 
match_string_constant, and use gfc_next_char instead of gfc_match_char 
in get_kind.

Mikael

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, v2] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 11:11 ` Mikael Morin
@ 2022-07-29 19:59   ` Harald Anlauf
  2022-07-29 19:59     ` Harald Anlauf
  2022-07-29 20:36     ` Mikael Morin
  0 siblings, 2 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-29 19:59 UTC (permalink / raw)
  To: Mikael Morin, fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]

Hi Mikael,

Am 29.07.22 um 13:11 schrieb Mikael Morin:
> Hello,
>
> Le 28/07/2022 à 22:11, Harald Anlauf via Fortran a écrit :
>> Dear all,
>>
>> in free-form mode, blanks are significant, so they cannot appear
>> in literal constants, especially not before or after the "_" that
>> separates the literal and the kind specifier.
>>
>> The initial patch from Steve addressed numerical literals, which
>> I completed by adjusting the parsing of string literals.
>>
>> Regtested on x86_64-pc-linux-gnu.  OK for mainline?
>>
> It looks correct, but I think we should continue to have the free vs
> fixed form abstracted away from the parsing code.

yes, that makes sense.

> So, I suggest instead to remove the calls to gfc_gobble_whitespace in
> match_string_constant,

Indeed, removing these simplifies the function and indeed works!

 > and use gfc_next_char instead of gfc_match_char
> in get_kind.

There is one important functionality in gfc_match_char(): it manages
the locus.  We would need then to add this explicitly to get_kind,
which does not look to me like a big improvement over the present
solution.  Otherwise I get test regressions.

> Mikael
>

I've attached a revised version with improved match_string_constant().
What do you think?

Thanks,
Harald

[-- Attachment #2: pr92805-v2.diff --]
[-- Type: text/x-patch, Size: 4301 bytes --]

From f8e7c297b7c9e5a2b22185c7e0d638764c33aa71 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* primary.cc (get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/primary.cc                        | 19 +++++++--------
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 3 files changed, 53 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..604f98a8dd9 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -92,14 +92,21 @@ get_kind (int *is_iso_c)
 {
   int kind;
   match m;
+  char c;
 
   *is_iso_c = 0;
 
+  c = gfc_peek_ascii_char ();
+  if (gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+    return -2;
+
   if (gfc_match_char ('_') != MATCH_YES)
     return -2;
 
-  m = match_kind_param (&kind, is_iso_c);
-  if (m == MATCH_NO)
+  m = MATCH_NO;
+  c = gfc_peek_ascii_char ();
+  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
     gfc_error ("Missing kind-parameter at %C");
 
   return (m == MATCH_YES) ? kind : -1;
@@ -1074,17 +1081,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, v2] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 19:59   ` [PATCH, v2] " Harald Anlauf
@ 2022-07-29 19:59     ` Harald Anlauf
  2022-07-29 20:36     ` Mikael Morin
  1 sibling, 0 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-29 19:59 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1273 bytes --]

Hi Mikael,

Am 29.07.22 um 13:11 schrieb Mikael Morin:
> Hello,
> 
> Le 28/07/2022 à 22:11, Harald Anlauf via Fortran a écrit :
>> Dear all,
>>
>> in free-form mode, blanks are significant, so they cannot appear
>> in literal constants, especially not before or after the "_" that
>> separates the literal and the kind specifier.
>>
>> The initial patch from Steve addressed numerical literals, which
>> I completed by adjusting the parsing of string literals.
>>
>> Regtested on x86_64-pc-linux-gnu.  OK for mainline?
>>
> It looks correct, but I think we should continue to have the free vs 
> fixed form abstracted away from the parsing code.

yes, that makes sense.

> So, I suggest instead to remove the calls to gfc_gobble_whitespace in 
> match_string_constant,

Indeed, removing these simplifies the function and indeed works!

 > and use gfc_next_char instead of gfc_match_char
> in get_kind.

There is one important functionality in gfc_match_char(): it manages
the locus.  We would need then to add this explicitly to get_kind,
which does not look to me like a big improvement over the present
solution.  Otherwise I get test regressions.

> Mikael
> 

I've attached a revised version with improved match_string_constant().
What do you think?

Thanks,
Harald

[-- Attachment #2: pr92805-v2.diff --]
[-- Type: text/x-patch, Size: 4301 bytes --]

From f8e7c297b7c9e5a2b22185c7e0d638764c33aa71 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* primary.cc (get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/primary.cc                        | 19 +++++++--------
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 3 files changed, 53 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..604f98a8dd9 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -92,14 +92,21 @@ get_kind (int *is_iso_c)
 {
   int kind;
   match m;
+  char c;
 
   *is_iso_c = 0;
 
+  c = gfc_peek_ascii_char ();
+  if (gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+    return -2;
+
   if (gfc_match_char ('_') != MATCH_YES)
     return -2;
 
-  m = match_kind_param (&kind, is_iso_c);
-  if (m == MATCH_NO)
+  m = MATCH_NO;
+  c = gfc_peek_ascii_char ();
+  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
     gfc_error ("Missing kind-parameter at %C");
 
   return (m == MATCH_YES) ? kind : -1;
@@ -1074,17 +1081,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v2] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 19:59   ` [PATCH, v2] " Harald Anlauf
  2022-07-29 19:59     ` Harald Anlauf
@ 2022-07-29 20:36     ` Mikael Morin
  2022-07-29 21:09       ` [PATCH, v3] " Harald Anlauf
  1 sibling, 1 reply; 15+ messages in thread
From: Mikael Morin @ 2022-07-29 20:36 UTC (permalink / raw)
  To: Harald Anlauf, fortran; +Cc: gcc-patches

Le 29/07/2022 à 21:59, Harald Anlauf via Fortran a écrit :
> 
> Am 29.07.22 um 13:11 schrieb Mikael Morin:
> 
>  > and use gfc_next_char instead of gfc_match_char
>> in get_kind.
> 
> There is one important functionality in gfc_match_char(): it manages
> the locus.  We would need then to add this explicitly to get_kind,
> which does not look to me like a big improvement over the present
> solution.  Otherwise I get test regressions.
> 
Indeed, I overlooked that, but my opinion remains that we shouldn’t play 
with fixed vs free form considerations here.
So the options I can see are:
  - handle the locus in get_kind; we do it a lot already in matching 
functions, so it wouldn’t be different here.
  - implement a variant of gfc_match_char without space gobbling.
  - use gfc_match(...), which is a bit heavy weight to match a single 
char string, but otherwise would keep things concise.

My preference goes to the third option, but I’m fine with either of them 
if you have a different one.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 20:36     ` Mikael Morin
@ 2022-07-29 21:09       ` Harald Anlauf
  2022-07-29 21:09         ` Harald Anlauf
                           ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-29 21:09 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 775 bytes --]

Hi Mikael,

Am 29.07.22 um 22:36 schrieb Mikael Morin:
> Indeed, I overlooked that, but my opinion remains that we shouldn’t play 
> with fixed vs free form considerations here.
> So the options I can see are:
>   - handle the locus in get_kind; we do it a lot already in matching 
> functions, so it wouldn’t be different here.
>   - implement a variant of gfc_match_char without space gobbling.
>   - use gfc_match(...), which is a bit heavy weight to match a single 
> char string, but otherwise would keep things concise.
> 
> My preference goes to the third option, but I’m fine with either of them 
> if you have a different one.
> 

how about the attached?

This introduces the helper function gfc_match_next_char, which is
your second option.

Thanks,
Harald

[-- Attachment #2: pr92805-v3.diff --]
[-- Type: text/x-patch, Size: 5695 bytes --]

From 0a95d103e4855fbcc20fd24d44b97b690d570333 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* gfortran.h (gfc_match_next_char): Declare it.
	* primary.cc (get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.
	* scanner.cc (gfc_match_next_char): New.  Match next character of
	input, treating whitespace depending on fixed or free form.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/gfortran.h                        |  1 +
 gcc/fortran/primary.cc                        | 17 +++++--------
 gcc/fortran/scanner.cc                        | 17 +++++++++++++
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 5 files changed, 68 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 696aadd7db6..645a30e7d49 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3209,6 +3209,7 @@ gfc_char_t gfc_next_char (void);
 char gfc_next_ascii_char (void);
 gfc_char_t gfc_peek_char (void);
 char gfc_peek_ascii_char (void);
+match gfc_match_next_char (gfc_char_t);
 void gfc_error_recovery (void);
 void gfc_gobble_whitespace (void);
 void gfc_new_file (void);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..9fa6779200f 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -92,14 +92,17 @@ get_kind (int *is_iso_c)
 {
   int kind;
   match m;
+  char c;
 
   *is_iso_c = 0;
 
-  if (gfc_match_char ('_') != MATCH_YES)
+  if (gfc_match_next_char ('_') != MATCH_YES)
     return -2;
 
-  m = match_kind_param (&kind, is_iso_c);
-  if (m == MATCH_NO)
+  m = MATCH_NO;
+  c = gfc_peek_ascii_char ();
+  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
     gfc_error ("Missing kind-parameter at %C");
 
   return (m == MATCH_YES) ? kind : -1;
@@ -1074,17 +1077,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/fortran/scanner.cc b/gcc/fortran/scanner.cc
index 2dff2514700..2d1980c074c 100644
--- a/gcc/fortran/scanner.cc
+++ b/gcc/fortran/scanner.cc
@@ -1690,6 +1690,23 @@ gfc_peek_ascii_char (void)
 }
 
 
+/* Match next character of input.  In fixed form mode, we also ignore
+   spaces.  */
+
+match
+gfc_match_next_char (gfc_char_t c)
+{
+  locus where;
+
+  where = gfc_current_locus;
+  if (gfc_next_char () == c)
+    return MATCH_YES;
+
+  gfc_current_locus = where;
+  return MATCH_NO;
+}
+
+
 /* Recover from an error.  We try to get past the current statement
    and get lined up for the next.  The next statement follows a '\n'
    or a ';'.  We also assume that we are not within a character
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 21:09       ` [PATCH, v3] " Harald Anlauf
@ 2022-07-29 21:09         ` Harald Anlauf
  2022-07-30  7:46         ` Thomas Koenig
  2022-07-30  8:28         ` Mikael Morin
  2 siblings, 0 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-29 21:09 UTC (permalink / raw)
  To: Mikael Morin, fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 793 bytes --]

Hi Mikael,

Am 29.07.22 um 22:36 schrieb Mikael Morin:
> Indeed, I overlooked that, but my opinion remains that we shouldn’t play
> with fixed vs free form considerations here.
> So the options I can see are:
>   - handle the locus in get_kind; we do it a lot already in matching
> functions, so it wouldn’t be different here.
>   - implement a variant of gfc_match_char without space gobbling.
>   - use gfc_match(...), which is a bit heavy weight to match a single
> char string, but otherwise would keep things concise.
>
> My preference goes to the third option, but I’m fine with either of them
> if you have a different one.
>

how about the attached?

This introduces the helper function gfc_match_next_char, which is
your second option.

Thanks,
Harald

[-- Attachment #2: pr92805-v3.diff --]
[-- Type: text/x-patch, Size: 5695 bytes --]

From 0a95d103e4855fbcc20fd24d44b97b690d570333 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* gfortran.h (gfc_match_next_char): Declare it.
	* primary.cc (get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.
	* scanner.cc (gfc_match_next_char): New.  Match next character of
	input, treating whitespace depending on fixed or free form.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/gfortran.h                        |  1 +
 gcc/fortran/primary.cc                        | 17 +++++--------
 gcc/fortran/scanner.cc                        | 17 +++++++++++++
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 5 files changed, 68 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 696aadd7db6..645a30e7d49 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3209,6 +3209,7 @@ gfc_char_t gfc_next_char (void);
 char gfc_next_ascii_char (void);
 gfc_char_t gfc_peek_char (void);
 char gfc_peek_ascii_char (void);
+match gfc_match_next_char (gfc_char_t);
 void gfc_error_recovery (void);
 void gfc_gobble_whitespace (void);
 void gfc_new_file (void);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..9fa6779200f 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -92,14 +92,17 @@ get_kind (int *is_iso_c)
 {
   int kind;
   match m;
+  char c;
 
   *is_iso_c = 0;
 
-  if (gfc_match_char ('_') != MATCH_YES)
+  if (gfc_match_next_char ('_') != MATCH_YES)
     return -2;
 
-  m = match_kind_param (&kind, is_iso_c);
-  if (m == MATCH_NO)
+  m = MATCH_NO;
+  c = gfc_peek_ascii_char ();
+  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
+      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
     gfc_error ("Missing kind-parameter at %C");
 
   return (m == MATCH_YES) ? kind : -1;
@@ -1074,17 +1077,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/fortran/scanner.cc b/gcc/fortran/scanner.cc
index 2dff2514700..2d1980c074c 100644
--- a/gcc/fortran/scanner.cc
+++ b/gcc/fortran/scanner.cc
@@ -1690,6 +1690,23 @@ gfc_peek_ascii_char (void)
 }
 
 
+/* Match next character of input.  In fixed form mode, we also ignore
+   spaces.  */
+
+match
+gfc_match_next_char (gfc_char_t c)
+{
+  locus where;
+
+  where = gfc_current_locus;
+  if (gfc_next_char () == c)
+    return MATCH_YES;
+
+  gfc_current_locus = where;
+  return MATCH_NO;
+}
+
+
 /* Recover from an error.  We try to get past the current statement
    and get lined up for the next.  The next statement follows a '\n'
    or a ';'.  We also assume that we are not within a character
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 21:09       ` [PATCH, v3] " Harald Anlauf
  2022-07-29 21:09         ` Harald Anlauf
@ 2022-07-30  7:46         ` Thomas Koenig
  2022-07-30 18:32           ` Harald Anlauf
  2022-07-30  8:28         ` Mikael Morin
  2 siblings, 1 reply; 15+ messages in thread
From: Thomas Koenig @ 2022-07-30  7:46 UTC (permalink / raw)
  To: Harald Anlauf, fortran; +Cc: gcc-patches


Hi Harald,

> This introduces the helper function gfc_match_next_char, which is
> your second option.

I would be a little bit concerned about compilation times
with the additional function call overhead.

The function is used only in one place; would it make
sense to put it into primary.cc and declare it static?

Best regards

	Thomas

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-29 21:09       ` [PATCH, v3] " Harald Anlauf
  2022-07-29 21:09         ` Harald Anlauf
  2022-07-30  7:46         ` Thomas Koenig
@ 2022-07-30  8:28         ` Mikael Morin
  2022-07-30 19:40           ` [PATCH, v4] " Harald Anlauf
  2 siblings, 1 reply; 15+ messages in thread
From: Mikael Morin @ 2022-07-30  8:28 UTC (permalink / raw)
  To: Harald Anlauf, fortran; +Cc: gcc-patches

Le 29/07/2022 à 23:09, Harald Anlauf via Fortran a écrit :
> Hi Mikael,
> 
> Am 29.07.22 um 22:36 schrieb Mikael Morin:
>> Indeed, I overlooked that, but my opinion remains that we shouldn’t 
>> play with fixed vs free form considerations here.
>> So the options I can see are:
>>   - handle the locus in get_kind; we do it a lot already in matching 
>> functions, so it wouldn’t be different here.
>>   - implement a variant of gfc_match_char without space gobbling.
>>   - use gfc_match(...), which is a bit heavy weight to match a single 
>> char string, but otherwise would keep things concise.
>>
>> My preference goes to the third option, but I’m fine with either of 
>> them if you have a different one.
>>
> 
> how about the attached?
> 
> This introduces the helper function gfc_match_next_char, which is
> your second option.
>
> diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
> index 3f01f67cd49..9fa6779200f 100644
> --- a/gcc/fortran/primary.cc
> +++ b/gcc/fortran/primary.cc
> @@ -92,14 +92,17 @@ get_kind (int *is_iso_c)
>  {
>    int kind;
>    match m;
> +  char c;
>  
>    *is_iso_c = 0;
>  
> -  if (gfc_match_char ('_') != MATCH_YES)
> +  if (gfc_match_next_char ('_') != MATCH_YES)
>      return -2;
>  
> -  m = match_kind_param (&kind, is_iso_c);
> -  if (m == MATCH_NO)
> +  m = MATCH_NO;
> +  c = gfc_peek_ascii_char ();
> +  if ((gfc_current_form == FORM_FREE && gfc_is_whitespace (c))
> +      || (m = match_kind_param (&kind, is_iso_c)) == MATCH_NO)
>      gfc_error ("Missing kind-parameter at %C");
>  
Meh! We killed one check for gfc_current_form but the other one is still 
there.
OK, match_kind_param calls two functions that also gobble space, so 
there is work remaining here.
So please make match_small_literal_constant and gfc_match_name 
space-gobbling wrappers around space-non-gobbling inner functions and 
call those inner functions instead in match_kind_param.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-30  7:46         ` Thomas Koenig
@ 2022-07-30 18:32           ` Harald Anlauf
  2022-07-30 18:32             ` Harald Anlauf
  0 siblings, 1 reply; 15+ messages in thread
From: Harald Anlauf @ 2022-07-30 18:32 UTC (permalink / raw)
  To: Thomas Koenig, fortran; +Cc: gcc-patches

Hi Thomas,

Am 30.07.22 um 09:46 schrieb Thomas Koenig via Fortran:
>
> Hi Harald,
>
>> This introduces the helper function gfc_match_next_char, which is
>> your second option.
>
> I would be a little bit concerned about compilation times
> with the additional function call overhead.

the function it replaces (gfc_match_char) is also in a different
file, thus the overhead is at least neutral.  Given that the latter
has an additional call to gfc_gobble_whitespace(), we actually get
better...

> The function is used only in one place; would it make
> sense to put it into primary.cc and declare it static?

Can do that.

> Best regards
>
>      Thomas
>

Thanks,
Harald

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v3] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-30 18:32           ` Harald Anlauf
@ 2022-07-30 18:32             ` Harald Anlauf
  0 siblings, 0 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-30 18:32 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches

Hi Thomas,

Am 30.07.22 um 09:46 schrieb Thomas Koenig via Fortran:
> 
> Hi Harald,
> 
>> This introduces the helper function gfc_match_next_char, which is
>> your second option.
> 
> I would be a little bit concerned about compilation times
> with the additional function call overhead.

the function it replaces (gfc_match_char) is also in a different
file, thus the overhead is at least neutral.  Given that the latter
has an additional call to gfc_gobble_whitespace(), we actually get
better...

> The function is used only in one place; would it make
> sense to put it into primary.cc and declare it static?

Can do that.

> Best regards
> 
>      Thomas
> 

Thanks,
Harald


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH, v4] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-30  8:28         ` Mikael Morin
@ 2022-07-30 19:40           ` Harald Anlauf
  2022-07-31  8:35             ` Mikael Morin
  0 siblings, 1 reply; 15+ messages in thread
From: Harald Anlauf @ 2022-07-30 19:40 UTC (permalink / raw)
  To: Mikael Morin, fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 909 bytes --]

Hi Mikael,

Am 30.07.22 um 10:28 schrieb Mikael Morin:
> Meh! We killed one check for gfc_current_form but the other one is still
> there.
> OK, match_kind_param calls two functions that also gobble space, so
> there is work remaining here.
> So please make match_small_literal_constant and gfc_match_name
> space-gobbling wrappers around space-non-gobbling inner functions and
> call those inner functions instead in match_kind_param.

well, here's the shortest solution I could come up with.
I added a new argument to 3 functions used in parsing that
controls the gobbling of whitespace.  We use this to handle
whitespace for numerical literals, while the parsing of string
literals remains as in the previous version of the patch.

This version obviously ignores Thomas' request, as that would
require to treat gfc_match_char specially...

Regtested again.  OK now?

Thanks,
Harald

[-- Attachment #2: pr92805-v4.diff --]
[-- Type: text/x-patch, Size: 7332 bytes --]

From cb33d1d0b91b371a864379d920ddaefc15d587f9 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* match.cc (gfc_match_small_literal_int): Make gobbling of leading
	whitespace optional.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* match.h (gfc_match_small_literal_int): Adjust prototype.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* primary.cc (match_kind_param): Match small literal int or name
	without gobbling whitespace.
	(get_kind): Do not skip over blanks in free-form mode.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/match.cc                          | 21 +++++++++-------
 gcc/fortran/match.h                           |  6 ++---
 gcc/fortran/primary.cc                        | 14 +++--------
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 5 files changed, 63 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 1aa3053e70e..c0dc0e89361 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -457,7 +457,7 @@ gfc_match_eos (void)
    will be set to the number of digits.  */
 
 match
-gfc_match_small_literal_int (int *value, int *cnt)
+gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
 {
   locus old_loc;
   char c;
@@ -466,7 +466,8 @@ gfc_match_small_literal_int (int *value, int *cnt)
   old_loc = gfc_current_locus;
 
   *value = -1;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
   c = gfc_next_ascii_char ();
   if (cnt)
     *cnt = 0;
@@ -611,14 +612,15 @@ gfc_match_label (void)
    than GFC_MAX_SYMBOL_LEN.  */
 
 match
-gfc_match_name (char *buffer)
+gfc_match_name (char *buffer, bool gobble_ws)
 {
   locus old_loc;
   int i;
   char c;
 
   old_loc = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   c = gfc_next_ascii_char ();
   if (!(ISALPHA (c) || (c == '_' && flag_allow_leading_underscore)))
@@ -1052,16 +1054,19 @@ cleanup:
 }
 
 
-/* Tries to match the next non-whitespace character on the input.
-   This subroutine does not return MATCH_ERROR.  */
+/* Tries to match the next non-whitespace character on the input.  This
+   subroutine does not return MATCH_ERROR.  When gobble_ws is false, do not
+   skip over leading blanks.
+*/
 
 match
-gfc_match_char (char c)
+gfc_match_char (char c, bool gobble_ws)
 {
   locus where;
 
   where = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   if (gfc_next_ascii_char () == c)
     return MATCH_YES;
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index 495c93e0b5c..1f53e0cb67d 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -45,14 +45,14 @@ extern gfc_access gfc_typebound_default_access;
 match gfc_match_special_char (gfc_char_t *);
 match gfc_match_space (void);
 match gfc_match_eos (void);
-match gfc_match_small_literal_int (int *, int *);
+match gfc_match_small_literal_int (int *, int *, bool = true);
 match gfc_match_st_label (gfc_st_label **);
 match gfc_match_small_int (int *);
-match gfc_match_name (char *);
+match gfc_match_name (char *, bool = true);
 match gfc_match_symbol (gfc_symbol **, int);
 match gfc_match_sym_tree (gfc_symtree **, int);
 match gfc_match_intrinsic_op (gfc_intrinsic_op *);
-match gfc_match_char (char);
+match gfc_match_char (char, bool = true);
 match gfc_match (const char *, ...);
 match gfc_match_iterator (gfc_iterator *, int);
 match gfc_match_parens (void);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..19f2e78c8ff 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -45,11 +45,11 @@ match_kind_param (int *kind, int *is_iso_c)
 
   *is_iso_c = 0;
 
-  m = gfc_match_small_literal_int (kind, NULL);
+  m = gfc_match_small_literal_int (kind, NULL, false);
   if (m != MATCH_NO)
     return m;
 
-  m = gfc_match_name (name);
+  m = gfc_match_name (name, false);
   if (m != MATCH_YES)
     return m;
 
@@ -95,7 +95,7 @@ get_kind (int *is_iso_c)
 
   *is_iso_c = 0;
 
-  if (gfc_match_char ('_') != MATCH_YES)
+  if (gfc_match_char ('_', false) != MATCH_YES)
     return -2;
 
   m = match_kind_param (&kind, is_iso_c);
@@ -1074,17 +1074,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v4] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-30 19:40           ` [PATCH, v4] " Harald Anlauf
@ 2022-07-31  8:35             ` Mikael Morin
  2022-07-31 19:01               ` Harald Anlauf
  0 siblings, 1 reply; 15+ messages in thread
From: Mikael Morin @ 2022-07-31  8:35 UTC (permalink / raw)
  To: Harald Anlauf, fortran; +Cc: gcc-patches

Le 30/07/2022 à 21:40, Harald Anlauf a écrit :
> Hi Mikael,
> 
> Am 30.07.22 um 10:28 schrieb Mikael Morin:
>> Meh! We killed one check for gfc_current_form but the other one is still
>> there.
>> OK, match_kind_param calls two functions that also gobble space, so
>> there is work remaining here.
>> So please make match_small_literal_constant and gfc_match_name
>> space-gobbling wrappers around space-non-gobbling inner functions and
>> call those inner functions instead in match_kind_param.
> 
> well, here's the shortest solution I could come up with.
> I added a new argument to 3 functions used in parsing that
> controls the gobbling of whitespace.  We use this to handle
> whitespace for numerical literals, while the parsing of string
> literals remains as in the previous version of the patch.
> 
> This version obviously ignores Thomas' request, as that would
> require to treat gfc_match_char specially...
> 
> Regtested again.  OK now?

> 	PR fortran/92805
> 	* match.cc (gfc_match_small_literal_int): Make gobbling of leading
> 	whitespace optional.
> 	(gfc_match_name): Likewise.
> 	(gfc_match_char): Likewise.
> 	* match.h (gfc_match_small_literal_int): Adjust prototype.
> 	(gfc_match_name): Likewise.
> 	(gfc_match_char): Likewise.
> 	* primary.cc (match_kind_param): Match small literal int or name
> 	without gobbling whitespace.
> 	(get_kind): Do not skip over blanks in free-form mode.
I think the "in free-form mode" applied to the preceding patches but can 
be dropped now.
> 	(match_string_constant): Likewise.

> diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
> index 1aa3053e70e..c0dc0e89361 100644
> --- a/gcc/fortran/match.cc
> +++ b/gcc/fortran/match.cc
> @@ -457,7 +457,7 @@ gfc_match_eos (void)
>     will be set to the number of digits.  */
Please add a note about GOBBLE_WS here, like you did for gfc_match_char.
> 
>  match
> -gfc_match_small_literal_int (int *value, int *cnt)
> +gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
>  {
>    locus old_loc;
>    char c;
(...)
> @@ -611,14 +612,15 @@ gfc_match_label (void)
>     than GFC_MAX_SYMBOL_LEN.  */
Same here.
>  
>  match
> -gfc_match_name (char *buffer)
> +gfc_match_name (char *buffer, bool gobble_ws)
>  {
>    locus old_loc;
>    int i;
>    char c;
>  
(...)
> @@ -1052,16 +1054,19 @@ cleanup:
>  }
>  
>  
> -/* Tries to match the next non-whitespace character on the input.
> -   This subroutine does not return MATCH_ERROR.  */
> +/* Tries to match the next non-whitespace character on the input.  This
> +   subroutine does not return MATCH_ERROR.  When gobble_ws is false, do not
> +   skip over leading blanks.
> +*/
There should be no line feed before end of comment.

OK with those changes.
thanks for your patience.

Mikael


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v4] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-31  8:35             ` Mikael Morin
@ 2022-07-31 19:01               ` Harald Anlauf
  2022-07-31 19:01                 ` Harald Anlauf
  0 siblings, 1 reply; 15+ messages in thread
From: Harald Anlauf @ 2022-07-31 19:01 UTC (permalink / raw)
  To: Mikael Morin, fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3249 bytes --]

Hi Mikael,

Am 31.07.22 um 10:35 schrieb Mikael Morin:
> Le 30/07/2022 à 21:40, Harald Anlauf a écrit :
>> Hi Mikael,
>>
>> Am 30.07.22 um 10:28 schrieb Mikael Morin:
>>> Meh! We killed one check for gfc_current_form but the other one is still
>>> there.
>>> OK, match_kind_param calls two functions that also gobble space, so
>>> there is work remaining here.
>>> So please make match_small_literal_constant and gfc_match_name
>>> space-gobbling wrappers around space-non-gobbling inner functions and
>>> call those inner functions instead in match_kind_param.
>>
>> well, here's the shortest solution I could come up with.
>> I added a new argument to 3 functions used in parsing that
>> controls the gobbling of whitespace.  We use this to handle
>> whitespace for numerical literals, while the parsing of string
>> literals remains as in the previous version of the patch.
>>
>> This version obviously ignores Thomas' request, as that would
>> require to treat gfc_match_char specially...
>>
>> Regtested again.  OK now?
>
>>     PR fortran/92805
>>     * match.cc (gfc_match_small_literal_int): Make gobbling of leading
>>     whitespace optional.
>>     (gfc_match_name): Likewise.
>>     (gfc_match_char): Likewise.
>>     * match.h (gfc_match_small_literal_int): Adjust prototype.
>>     (gfc_match_name): Likewise.
>>     (gfc_match_char): Likewise.
>>     * primary.cc (match_kind_param): Match small literal int or name
>>     without gobbling whitespace.
>>     (get_kind): Do not skip over blanks in free-form mode.
> I think the "in free-form mode" applied to the preceding patches but can
> be dropped now.
>>     (match_string_constant): Likewise.
>
>> diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
>> index 1aa3053e70e..c0dc0e89361 100644
>> --- a/gcc/fortran/match.cc
>> +++ b/gcc/fortran/match.cc
>> @@ -457,7 +457,7 @@ gfc_match_eos (void)
>>     will be set to the number of digits.  */
> Please add a note about GOBBLE_WS here, like you did for gfc_match_char.
>>
>>  match
>> -gfc_match_small_literal_int (int *value, int *cnt)
>> +gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
>>  {
>>    locus old_loc;
>>    char c;
> (...)
>> @@ -611,14 +612,15 @@ gfc_match_label (void)
>>     than GFC_MAX_SYMBOL_LEN.  */
> Same here.
>>
>>  match
>> -gfc_match_name (char *buffer)
>> +gfc_match_name (char *buffer, bool gobble_ws)
>>  {
>>    locus old_loc;
>>    int i;
>>    char c;
>>
> (...)
>> @@ -1052,16 +1054,19 @@ cleanup:
>>  }
>>
>>
>> -/* Tries to match the next non-whitespace character on the input.
>> -   This subroutine does not return MATCH_ERROR.  */
>> +/* Tries to match the next non-whitespace character on the input.  This
>> +   subroutine does not return MATCH_ERROR.  When gobble_ws is false,
>> do not
>> +   skip over leading blanks.
>> +*/
> There should be no line feed before end of comment.

I've adjusted the patch (see attached) and pushed it as

commit r13-1905-gd325e7048c85e13f12ea79aebf9623eddc7ffcaf

Thanks,
Harald

> OK with those changes.
> thanks for your patience.
>
> Mikael
>
>

[-- Attachment #2: pr92805-v5.diff --]
[-- Type: text/x-patch, Size: 7856 bytes --]

From d325e7048c85e13f12ea79aebf9623eddc7ffcaf Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* match.cc (gfc_match_small_literal_int): Make gobbling of leading
	whitespace optional.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* match.h (gfc_match_small_literal_int): Adjust prototype.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* primary.cc (match_kind_param): Match small literal int or name
	without gobbling whitespace.
	(get_kind): Do not skip over blanks.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/match.cc                          | 24 ++++++++++++-------
 gcc/fortran/match.h                           |  6 ++---
 gcc/fortran/primary.cc                        | 14 +++--------
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 5 files changed, 65 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 1aa3053e70e..8b8b6e79c8b 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -454,10 +454,11 @@ gfc_match_eos (void)
 /* Match a literal integer on the input, setting the value on
    MATCH_YES.  Literal ints occur in kind-parameters as well as
    old-style character length specifications.  If cnt is non-NULL it
-   will be set to the number of digits.  */
+   will be set to the number of digits.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_small_literal_int (int *value, int *cnt)
+gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
 {
   locus old_loc;
   char c;
@@ -466,7 +467,8 @@ gfc_match_small_literal_int (int *value, int *cnt)
   old_loc = gfc_current_locus;
 
   *value = -1;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
   c = gfc_next_ascii_char ();
   if (cnt)
     *cnt = 0;
@@ -608,17 +610,19 @@ gfc_match_label (void)
 /* See if the current input looks like a name of some sort.  Modifies
    the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long.
    Note that options.cc restricts max_identifier_length to not more
-   than GFC_MAX_SYMBOL_LEN.  */
+   than GFC_MAX_SYMBOL_LEN.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_name (char *buffer)
+gfc_match_name (char *buffer, bool gobble_ws)
 {
   locus old_loc;
   int i;
   char c;
 
   old_loc = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   c = gfc_next_ascii_char ();
   if (!(ISALPHA (c) || (c == '_' && flag_allow_leading_underscore)))
@@ -1053,15 +1057,17 @@ cleanup:
 
 
 /* Tries to match the next non-whitespace character on the input.
-   This subroutine does not return MATCH_ERROR.  */
+   This subroutine does not return MATCH_ERROR.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_char (char c)
+gfc_match_char (char c, bool gobble_ws)
 {
   locus where;
 
   where = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   if (gfc_next_ascii_char () == c)
     return MATCH_YES;
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index 495c93e0b5c..1f53e0cb67d 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -45,14 +45,14 @@ extern gfc_access gfc_typebound_default_access;
 match gfc_match_special_char (gfc_char_t *);
 match gfc_match_space (void);
 match gfc_match_eos (void);
-match gfc_match_small_literal_int (int *, int *);
+match gfc_match_small_literal_int (int *, int *, bool = true);
 match gfc_match_st_label (gfc_st_label **);
 match gfc_match_small_int (int *);
-match gfc_match_name (char *);
+match gfc_match_name (char *, bool = true);
 match gfc_match_symbol (gfc_symbol **, int);
 match gfc_match_sym_tree (gfc_symtree **, int);
 match gfc_match_intrinsic_op (gfc_intrinsic_op *);
-match gfc_match_char (char);
+match gfc_match_char (char, bool = true);
 match gfc_match (const char *, ...);
 match gfc_match_iterator (gfc_iterator *, int);
 match gfc_match_parens (void);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..19f2e78c8ff 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -45,11 +45,11 @@ match_kind_param (int *kind, int *is_iso_c)
 
   *is_iso_c = 0;
 
-  m = gfc_match_small_literal_int (kind, NULL);
+  m = gfc_match_small_literal_int (kind, NULL, false);
   if (m != MATCH_NO)
     return m;
 
-  m = gfc_match_name (name);
+  m = gfc_match_name (name, false);
   if (m != MATCH_YES)
     return m;
 
@@ -95,7 +95,7 @@ get_kind (int *is_iso_c)
 
   *is_iso_c = 0;
 
-  if (gfc_match_char ('_') != MATCH_YES)
+  if (gfc_match_char ('_', false) != MATCH_YES)
     return -2;
 
   m = match_kind_param (&kind, is_iso_c);
@@ -1074,17 +1074,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH, v4] Fortran: detect blanks within literal constants in free-form mode [PR92805]
  2022-07-31 19:01               ` Harald Anlauf
@ 2022-07-31 19:01                 ` Harald Anlauf
  0 siblings, 0 replies; 15+ messages in thread
From: Harald Anlauf @ 2022-07-31 19:01 UTC (permalink / raw)
  To: fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3161 bytes --]

Hi Mikael,

Am 31.07.22 um 10:35 schrieb Mikael Morin:
> Le 30/07/2022 à 21:40, Harald Anlauf a écrit :
>> Hi Mikael,
>>
>> Am 30.07.22 um 10:28 schrieb Mikael Morin:
>>> Meh! We killed one check for gfc_current_form but the other one is still
>>> there.
>>> OK, match_kind_param calls two functions that also gobble space, so
>>> there is work remaining here.
>>> So please make match_small_literal_constant and gfc_match_name
>>> space-gobbling wrappers around space-non-gobbling inner functions and
>>> call those inner functions instead in match_kind_param.
>>
>> well, here's the shortest solution I could come up with.
>> I added a new argument to 3 functions used in parsing that
>> controls the gobbling of whitespace.  We use this to handle
>> whitespace for numerical literals, while the parsing of string
>> literals remains as in the previous version of the patch.
>>
>> This version obviously ignores Thomas' request, as that would
>> require to treat gfc_match_char specially...
>>
>> Regtested again.  OK now?
> 
>>     PR fortran/92805
>>     * match.cc (gfc_match_small_literal_int): Make gobbling of leading
>>     whitespace optional.
>>     (gfc_match_name): Likewise.
>>     (gfc_match_char): Likewise.
>>     * match.h (gfc_match_small_literal_int): Adjust prototype.
>>     (gfc_match_name): Likewise.
>>     (gfc_match_char): Likewise.
>>     * primary.cc (match_kind_param): Match small literal int or name
>>     without gobbling whitespace.
>>     (get_kind): Do not skip over blanks in free-form mode.
> I think the "in free-form mode" applied to the preceding patches but can 
> be dropped now.
>>     (match_string_constant): Likewise.
> 
>> diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
>> index 1aa3053e70e..c0dc0e89361 100644
>> --- a/gcc/fortran/match.cc
>> +++ b/gcc/fortran/match.cc
>> @@ -457,7 +457,7 @@ gfc_match_eos (void)
>>     will be set to the number of digits.  */
> Please add a note about GOBBLE_WS here, like you did for gfc_match_char.
>>
>>  match
>> -gfc_match_small_literal_int (int *value, int *cnt)
>> +gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
>>  {
>>    locus old_loc;
>>    char c;
> (...)
>> @@ -611,14 +612,15 @@ gfc_match_label (void)
>>     than GFC_MAX_SYMBOL_LEN.  */
> Same here.
>>
>>  match
>> -gfc_match_name (char *buffer)
>> +gfc_match_name (char *buffer, bool gobble_ws)
>>  {
>>    locus old_loc;
>>    int i;
>>    char c;
>>
> (...)
>> @@ -1052,16 +1054,19 @@ cleanup:
>>  }
>>
>>
>> -/* Tries to match the next non-whitespace character on the input.
>> -   This subroutine does not return MATCH_ERROR.  */
>> +/* Tries to match the next non-whitespace character on the input.  This
>> +   subroutine does not return MATCH_ERROR.  When gobble_ws is false, 
>> do not
>> +   skip over leading blanks.
>> +*/
> There should be no line feed before end of comment.

I've adjusted the patch (see attached) and pushed it as

commit r13-1905-gd325e7048c85e13f12ea79aebf9623eddc7ffcaf

Thanks,
Harald

> OK with those changes.
> thanks for your patience.
> 
> Mikael
> 
> 

[-- Attachment #2: pr92805-v5.diff --]
[-- Type: text/x-patch, Size: 7856 bytes --]

From d325e7048c85e13f12ea79aebf9623eddc7ffcaf Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 28 Jul 2022 22:07:02 +0200
Subject: [PATCH] Fortran: detect blanks within literal constants in free-form
 mode [PR92805]

gcc/fortran/ChangeLog:

	PR fortran/92805
	* match.cc (gfc_match_small_literal_int): Make gobbling of leading
	whitespace optional.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* match.h (gfc_match_small_literal_int): Adjust prototype.
	(gfc_match_name): Likewise.
	(gfc_match_char): Likewise.
	* primary.cc (match_kind_param): Match small literal int or name
	without gobbling whitespace.
	(get_kind): Do not skip over blanks.
	(match_string_constant): Likewise.

gcc/testsuite/ChangeLog:

	PR fortran/92805
	* gfortran.dg/literal_constants.f: New test.
	* gfortran.dg/literal_constants.f90: New test.

Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
---
 gcc/fortran/match.cc                          | 24 ++++++++++++-------
 gcc/fortran/match.h                           |  6 ++---
 gcc/fortran/primary.cc                        | 14 +++--------
 gcc/testsuite/gfortran.dg/literal_constants.f | 20 ++++++++++++++++
 .../gfortran.dg/literal_constants.f90         | 24 +++++++++++++++++++
 5 files changed, 65 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f
 create mode 100644 gcc/testsuite/gfortran.dg/literal_constants.f90

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 1aa3053e70e..8b8b6e79c8b 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -454,10 +454,11 @@ gfc_match_eos (void)
 /* Match a literal integer on the input, setting the value on
    MATCH_YES.  Literal ints occur in kind-parameters as well as
    old-style character length specifications.  If cnt is non-NULL it
-   will be set to the number of digits.  */
+   will be set to the number of digits.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_small_literal_int (int *value, int *cnt)
+gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
 {
   locus old_loc;
   char c;
@@ -466,7 +467,8 @@ gfc_match_small_literal_int (int *value, int *cnt)
   old_loc = gfc_current_locus;
 
   *value = -1;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
   c = gfc_next_ascii_char ();
   if (cnt)
     *cnt = 0;
@@ -608,17 +610,19 @@ gfc_match_label (void)
 /* See if the current input looks like a name of some sort.  Modifies
    the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long.
    Note that options.cc restricts max_identifier_length to not more
-   than GFC_MAX_SYMBOL_LEN.  */
+   than GFC_MAX_SYMBOL_LEN.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_name (char *buffer)
+gfc_match_name (char *buffer, bool gobble_ws)
 {
   locus old_loc;
   int i;
   char c;
 
   old_loc = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   c = gfc_next_ascii_char ();
   if (!(ISALPHA (c) || (c == '_' && flag_allow_leading_underscore)))
@@ -1053,15 +1057,17 @@ cleanup:
 
 
 /* Tries to match the next non-whitespace character on the input.
-   This subroutine does not return MATCH_ERROR.  */
+   This subroutine does not return MATCH_ERROR.
+   When gobble_ws is false, do not skip over leading blanks.  */
 
 match
-gfc_match_char (char c)
+gfc_match_char (char c, bool gobble_ws)
 {
   locus where;
 
   where = gfc_current_locus;
-  gfc_gobble_whitespace ();
+  if (gobble_ws)
+    gfc_gobble_whitespace ();
 
   if (gfc_next_ascii_char () == c)
     return MATCH_YES;
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index 495c93e0b5c..1f53e0cb67d 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -45,14 +45,14 @@ extern gfc_access gfc_typebound_default_access;
 match gfc_match_special_char (gfc_char_t *);
 match gfc_match_space (void);
 match gfc_match_eos (void);
-match gfc_match_small_literal_int (int *, int *);
+match gfc_match_small_literal_int (int *, int *, bool = true);
 match gfc_match_st_label (gfc_st_label **);
 match gfc_match_small_int (int *);
-match gfc_match_name (char *);
+match gfc_match_name (char *, bool = true);
 match gfc_match_symbol (gfc_symbol **, int);
 match gfc_match_sym_tree (gfc_symtree **, int);
 match gfc_match_intrinsic_op (gfc_intrinsic_op *);
-match gfc_match_char (char);
+match gfc_match_char (char, bool = true);
 match gfc_match (const char *, ...);
 match gfc_match_iterator (gfc_iterator *, int);
 match gfc_match_parens (void);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 3f01f67cd49..19f2e78c8ff 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -45,11 +45,11 @@ match_kind_param (int *kind, int *is_iso_c)
 
   *is_iso_c = 0;
 
-  m = gfc_match_small_literal_int (kind, NULL);
+  m = gfc_match_small_literal_int (kind, NULL, false);
   if (m != MATCH_NO)
     return m;
 
-  m = gfc_match_name (name);
+  m = gfc_match_name (name, false);
   if (m != MATCH_YES)
     return m;
 
@@ -95,7 +95,7 @@ get_kind (int *is_iso_c)
 
   *is_iso_c = 0;
 
-  if (gfc_match_char ('_') != MATCH_YES)
+  if (gfc_match_char ('_', false) != MATCH_YES)
     return -2;
 
   m = match_kind_param (&kind, is_iso_c);
@@ -1074,17 +1074,9 @@ match_string_constant (gfc_expr **result)
       c = gfc_next_char ();
     }
 
-  if (c == ' ')
-    {
-      gfc_gobble_whitespace ();
-      c = gfc_next_char ();
-    }
-
   if (c != '_')
     goto no_match;
 
-  gfc_gobble_whitespace ();
-
   c = gfc_next_char ();
   if (c != '\'' && c != '"')
     goto no_match;
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f b/gcc/testsuite/gfortran.dg/literal_constants.f
new file mode 100644
index 00000000000..4d1f1b7eb4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form" }
+! PR fortran/92805 - blanks within literal constants in fixed-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"
+      print *, 1_ "abc"
+      print *, ck_"a"
+      print *, ck _"ab"
+      print *, ck_ "ab"
+      print *, 3.1415_4
+      print *, 3.1415 _4
+      print *, 3.1415_ 4
+      print *, 3.1415_rk
+      print *, 3.1415 _rk
+      print *, 3.1415_ rk
+      end
diff --git a/gcc/testsuite/gfortran.dg/literal_constants.f90 b/gcc/testsuite/gfortran.dg/literal_constants.f90
new file mode 100644
index 00000000000..f8908f9ad76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/literal_constants.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-ffree-form" }
+! PR fortran/92805 - blanks within literal constants in free-form mode
+
+      implicit none
+      integer, parameter :: ck = kind ("a")  ! default character kind
+      integer, parameter :: rk = kind (1.0)  ! default real kind
+      print *, 1_"abc"
+      print *, 1 _"abc"   ! { dg-error "Syntax error" }
+      print *, 1_ "abc"   ! { dg-error "Missing kind-parameter" }
+      print *, 1 _ "abc"  ! { dg-error "Syntax error" }
+      print *, ck_"a"
+      print *, ck _"ab"   ! { dg-error "Syntax error" }
+      print *, ck_ "ab"   ! { dg-error "Syntax error" }
+      print *, ck _ "ab"  ! { dg-error "Syntax error" }
+      print *, 3.1415_4
+      print *, 3.1415 _4  ! { dg-error "Syntax error" }
+      print *, 3.1415_ 4  ! { dg-error "Missing kind-parameter" }
+      print *, 3.1415 _ 4 ! { dg-error "Syntax error" }
+      print *, 3.1415_rk
+      print *, 3.1415 _rk ! { dg-error "Syntax error" }
+      print *, 3.1415_ rk ! { dg-error "Missing kind-parameter" }
+      print *, 3.141 _ rk ! { dg-error "Syntax error" }
+      end
-- 
2.35.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-07-31 19:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 20:11 [PATCH] Fortran: detect blanks within literal constants in free-form mode [PR92805] Harald Anlauf
2022-07-29 11:11 ` Mikael Morin
2022-07-29 19:59   ` [PATCH, v2] " Harald Anlauf
2022-07-29 19:59     ` Harald Anlauf
2022-07-29 20:36     ` Mikael Morin
2022-07-29 21:09       ` [PATCH, v3] " Harald Anlauf
2022-07-29 21:09         ` Harald Anlauf
2022-07-30  7:46         ` Thomas Koenig
2022-07-30 18:32           ` Harald Anlauf
2022-07-30 18:32             ` Harald Anlauf
2022-07-30  8:28         ` Mikael Morin
2022-07-30 19:40           ` [PATCH, v4] " Harald Anlauf
2022-07-31  8:35             ` Mikael Morin
2022-07-31 19:01               ` Harald Anlauf
2022-07-31 19:01                 ` Harald Anlauf

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).