[Fortran] Fix PR 82372

Message ID 8f13912c-0bf1-b570-cf72-a32b1bef2e26@netcologne.de
State New
Headers show
Series
  • [Fortran] Fix PR 82372
Related show

Commit Message

Thomas Koenig Oct. 10, 2017, 5:42 p.m.
Hello world,

the attached patch displays an error for characters which are
outside the normal Fortran character set, and includes a hex
code when it is not printable.

gfortran 4.9 did display unprintable characters in the file,
so it might be argued that this bug is a regression.

Regression-tested. OK for trunk? What do people feel about backporting?

Regards

	Thomas

2017-10-10  Thomas Koenig  <tkoenig@gcc.gnu.org>

         PR fortran/82372
         * fortran/scanner.c (valid_chars): String with all characters
         which could be valid in Fortran.
         (valid_table):  Boolean table to select valid characters.
         (gfc_scanner_init_1): Set up valid_table from vaid_chars.
         (gfc_gooble_whitespace): If a character not in the Fortran
         character set appears, display error.

2017-10-10  Thomas Koenig  <tkoenig@gcc.gnu.org>

         PR fortran/82372
         * gfortran.dg/illegal_char.f90: New test.

Comments

Steve Kargl Oct. 10, 2017, 6:06 p.m. | #1
On Tue, Oct 10, 2017 at 07:42:25PM +0200, Thomas Koenig wrote:
> Hello world,
> 
> the attached patch displays an error for characters which are
> outside the normal Fortran character set, and includes a hex

If this              ^^^^^^^^^^^^^^^^^^^^^

> code when it is not printable.
> 
> gfortran 4.9 did display unprintable characters in the file,
> so it might be argued that this bug is a regression.
> 
> Regression-tested. OK for trunk? What do people feel about backporting?
> 
> Regards
> 
> 	Thomas
> 
> 2017-10-10  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>          PR fortran/82372
>          * fortran/scanner.c (valid_chars): String with all characters
>          which could be valid in Fortran.

corresponds to this statement,

>          (valid_table):  Boolean table to select valid characters.
>          (gfc_scanner_init_1): Set up valid_table from vaid_chars.
>          (gfc_gooble_whitespace): If a character not in the Fortran
>          character set appears, display error.
> 
> 2017-10-10  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>          PR fortran/82372
>          * gfortran.dg/illegal_char.f90: New test.

> Index: fortran/scanner.c
> ===================================================================
> --- fortran/scanner.c	(Revision 253530)
> +++ fortran/scanner.c	(Arbeitskopie)
> @@ -80,7 +80,14 @@ static struct gfc_file_change
>  size_t file_changes_cur, file_changes_count;
>  size_t file_changes_allocated;
>  
> +char valid_chars[] =
> +  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
> +  "=+*-/^%[].,\n\t\r'\"();:<>_!$&0123456789";

then this is not correct.  From F2003, letters, digits, 
underscore, and special characters (see Table 3.1) are
members of the Fortran character set.  Your string includes
\n, \t, and \r, which are not in the Fortran character set.
Your string is missing \, {, }, ~, `, |, #, and @.
Thomas Koenig Oct. 10, 2017, 7:01 p.m. | #2
Hi Steve,

>> the attached patch displays an error for characters which are
>> outside the normal Fortran character set, and includes a hex
> 
> If this              ^^^^^^^^^^^^^^^^^^^^^

> corresponds to this statement,
> 
>>   
>> +char valid_chars[] =
>> +  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
>> +  "=+*-/^%[].,\n\t\r'\"();:<>_!$&0123456789";
> 
> then this is not correct.

You're correct, my statement above was misleading.

What I meant was the characters which can occur inside
normal Fortran syntax, plus a few more places, such as an
!$OMP statement.

>From F2003, letters, digits,
> underscore, and special characters (see Table 3.1) are
> members of the Fortran character set.  Your string includes
> \n, \t, and \r, which are not in the Fortran character set.
\t we warn about separetely. \n and \r can occur during parsing,
so we should not warn about them,

> Your string is missing \, {, }, ~, `, |, #, and @.

AFAIK, none of these characters can come up in an normal Fortran
statement except for a comment, string, format or continuation
character in fixed form.

Regards

	Thomas

Patch

Index: fortran/scanner.c
===================================================================
--- fortran/scanner.c	(Revision 253530)
+++ fortran/scanner.c	(Arbeitskopie)
@@ -80,7 +80,14 @@  static struct gfc_file_change
 size_t file_changes_cur, file_changes_count;
 size_t file_changes_allocated;
 
+char valid_chars[] =
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+  "=+*-/^%[].,\n\t\r'\"();:<>_!$&0123456789";
 
+bool valid_table[256];
+
+/* Lookup table to see which characters are valid. */
+
 /* Functions dealing with our wide characters (gfc_char_t) and
    sequences of such characters.  */
 
@@ -261,6 +268,9 @@  gfc_wide_strncasecmp (const gfc_char_t *s1, const
 void
 gfc_scanner_init_1 (void)
 {
+  char *p;
+  int i;
+
   file_head = NULL;
   line_head = NULL;
   line_tail = NULL;
@@ -269,6 +279,12 @@  gfc_scanner_init_1 (void)
   continue_line = 0;
 
   end_flag = 0;
+
+  for (p = valid_chars; *p; p++)
+    {
+      i = *p;
+      valid_table[i] = true;
+    }
 }
 
 
@@ -1680,6 +1696,8 @@  gfc_gobble_whitespace (void)
   static int linenum = 0;
   locus old_loc;
   gfc_char_t c;
+  static gfc_char_t dummy;
+  static gfc_char_t *last_error_char = &dummy;
 
   do
     {
@@ -1700,6 +1718,20 @@  gfc_gobble_whitespace (void)
     }
   while (gfc_is_whitespace (c));
 
+  if ((c > 256 || !valid_table[c])
+      && last_error_char != gfc_current_locus.nextc)
+    {
+      if (ISPRINT (c))
+	gfc_error_now ("Invalid character '%c' at %C", c);
+      else
+	{
+	  char buf[20];
+	  snprintf (buf, 20, "%2.2X", c);
+	  gfc_error_now ("Invalid character 0x%s at %C", buf);
+	}
+      last_error_char = gfc_current_locus.nextc;
+    }
+
   gfc_current_locus = old_loc;
 }
 
Index: testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95
===================================================================
--- testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95	(Revision 253530)
+++ testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95	(Arbeitskopie)
@@ -37,11 +37,11 @@  program test
   !$acc kernels async() { dg-error "Invalid character" }
   !$acc parallel async() { dg-error "Invalid character" }
 
-  !$acc kernels async("a") { dg-error "Unclassifiable" }
-  !$acc parallel async("a") { dg-error "Unclassifiable" }
+  !$acc kernels async("a") ! { dg-error "Unclassifiable" }
+  !$acc parallel async("a") ! { dg-error "Unclassifiable" }
 
-  !$acc kernels async(.true.) { dg-error "Unclassifiable" }
-  !$acc parallel async(.true.) { dg-error "Unclassifiable" }
+  !$acc kernels async(.true.) ! { dg-error "Unclassifiable" }
+  !$acc parallel async(.true.) ! { dg-error "Unclassifiable" }
 
   ! default(none)
   !$acc kernels default(none)
@@ -59,8 +59,8 @@  program test
   !$acc parallel default ( none )
   !$acc end parallel
 
-  !$acc kernels default { dg-error "Unclassifiable" }
-  !$acc parallel default { dg-error "Unclassifiable" }
+  !$acc kernels default ! { dg-error "Unclassifiable" }
+  !$acc parallel default ! { dg-error "Unclassifiable" }
 
   !$acc kernels default() { dg-error "Unclassifiable" }
   !$acc parallel default() { dg-error "Unclassifiable" }
Index: testsuite/gfortran.dg/typebound_proc_4.f03
===================================================================
--- testsuite/gfortran.dg/typebound_proc_4.f03	(Revision 253530)
+++ testsuite/gfortran.dg/typebound_proc_4.f03	(Arbeitskopie)
@@ -14,7 +14,7 @@  MODULE testmod
     PROCEDURE p1 => proc1 ! { dg-error "::" }
     PROCEDURE :: ! { dg-error "Expected binding name" }
     PROCEDURE ! { dg-error "Expected binding name" }
-    PROCEDURE ? ! { dg-error "Expected binding name" }
+    PROCEDURE ? ! { dg-error "Expected binding name|Invalid character" }
     PROCEDURE :: p2 => ! { dg-error "Expected binding target" }
     PROCEDURE :: p3 =>, ! { dg-error "Expected binding target" }
     PROCEDURE p4, ! { dg-error "Expected binding name" }