public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fortran include line fixes and -fdec-include support
@ 2018-11-12 14:51 Jakub Jelinek
  2018-11-12 23:25 ` Fritz Reese
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Jakub Jelinek @ 2018-11-12 14:51 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Mark Eggleston, Jeff Law

Hi!

In fortran97.pdf I read:
"Except in a character context, blanks are insignificant and may be used freely throughout the program."
and while we handle that in most cases, we don't allow spaces in INCLUDE
lines in fixed form, while e.g. ifort does.

Another thing, which I haven't touched in the PR except covering it with a
testcase is that we allow INLINE line in fixed form to start even in columns
1 to 6, while ifort rejects that.  Is say
     include 'omp_lib.h'
valid in fixed form?  i in column 6 normally means a continuation line,
though not sure if anything can in a valid program contain nclude
followed by character literal.  Shall we reject that, or at least warn that
it won't be portable?

The last thing, biggest part of the patch, is that for legacy DEC
compatibility, the DEC manuals document INCLUDE as a statement, not a line,
the
"An INCLUDE line is not a Fortran statement."
and
"An INCLUDE line shall appear on a single source line where a statement may appear; it shall be
the only nonblank text on this line other than an optional trailing comment. Thus, a statement
label is not allowed."
bullets don't apply, but instead there is:
"The INCLUDE statement takes one of the following forms:"
"An INCLUDE statement can appear anywhere within a scoping unit. The statement
can span more than one source line, but no other statement can appear on the same
line. The source line cannot be labeled."

This means there can be (as can be seen in the following testcases)
continuations in both forms, and in fixed form there can be 0 in column 6.

In order not to duplicate all the handling of continuations, comment
skipping etc., the patch just adjusts the include_line routine so that it
signals if the current line is a possible start of a valid INCLUDE statement
when in -fdec-include mode, and if so, whenever it reads a further line it
retries to parse it using
gfc_next_char/gfc_next_char_literal/gfc_gobble_whitespace APIs as an INCLUDE
stmt.  If it is found not to be a valid INCLUDE statement line or set of
lines, it returns 0, if it is valid, it returns 1 together with load_file
like include_line does and clears all the lines containint the INCLUDE
statement.  If the reading stops because we don't have enough lines, -1 is
returned and the caller tries again with more lines.

Tested on x86_64-linux, ok for trunk if it passes full bootstrap/regtest?

In addition to the above mentioned question about include in columns 1-6 in
fixed form, another thing is that we support
      print *, 'abc''def'
      print *, "hij""klm"
which prints abc'def and hij"klm.  Shall we support that for INCLUDE lines
and INCLUDE statements too?

2018-11-12  Jakub Jelinek  <jakub@redhat.com>
	    Mark Eggleston  <mark.eggleston@codethink.com>

	* lang.opt (fdec-include): New option.
	* options.c (set_dec_flags): Set also flag_dec_include.
	* scanner.c (include_line): Change return type from bool to int.
	In fixed form allow spaces in between include keyword letters.
	For -fdec-include, allow in fixed form 0 in column 6.  With
	-fdec-include return -1 if the parsed line is not full include
	statement and it could be successfully completed on continuation
	lines.
	(include_stmt): New function.
	(load_file): Adjust include_line caller.  If it returns -1, keep
	trying include_stmt until it stops returning -1 whenever adding
	further line of input.

	* gfortran.dg/include_10.f: New test.
	* gfortran.dg/include_10.inc: New file.
	* gfortran.dg/include_11.f: New test.
	* gfortran.dg/include_12.f: New test.
	* gfortran.dg/include_13.f90: New test.
	* gfortran.dg/gomp/include_1.f: New test.
	* gfortran.dg/gomp/include_1.inc: New file.
	* gfortran.dg/gomp/include_2.f90: New test.

--- gcc/fortran/lang.opt.jj	2018-07-18 22:57:15.227785894 +0200
+++ gcc/fortran/lang.opt	2018-11-12 09:35:03.185259773 +0100
@@ -440,6 +440,10 @@ fdec
 Fortran Var(flag_dec)
 Enable all DEC language extensions.
 
+fdec-include
+Fortran Var(flag_dec_include)
+Enable legacy parsing of INCLUDE as statement.
+
 fdec-intrinsic-ints
 Fortran Var(flag_dec_intrinsic_ints)
 Enable kind-specific variants of integer intrinsic functions.
--- gcc/fortran/options.c.jj	2018-11-06 18:27:13.828831733 +0100
+++ gcc/fortran/options.c	2018-11-12 09:35:39.515655453 +0100
@@ -68,6 +68,7 @@ set_dec_flags (int value)
   flag_dec_intrinsic_ints |= value;
   flag_dec_static |= value;
   flag_dec_math |= value;
+  flag_dec_include |= value;
 }
 
 
--- gcc/fortran/scanner.c.jj	2018-05-08 13:56:41.691932534 +0200
+++ gcc/fortran/scanner.c	2018-11-12 15:21:51.249391936 +0100
@@ -2135,14 +2135,18 @@ static bool load_file (const char *, con
 /* include_line()-- Checks a line buffer to see if it is an include
    line.  If so, we call load_file() recursively to load the included
    file.  We never return a syntax error because a statement like
-   "include = 5" is perfectly legal.  We return false if no include was
-   processed or true if we matched an include.  */
+   "include = 5" is perfectly legal.  We return 0 if no include was
+   processed, 1 if we matched an include or -1 if include was
+   partially processed, but will need continuation lines.  */
 
-static bool
+static int
 include_line (gfc_char_t *line)
 {
   gfc_char_t quote, *c, *begin, *stop;
   char *filename;
+  const char *include = "include";
+  bool allow_continuation = flag_dec_include;
+  int i;
 
   c = line;
 
@@ -2158,42 +2162,133 @@ include_line (gfc_char_t *line)
       else
 	{
 	  if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
-	      && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
+	      && c[1] == '$' && c[2] == ' ')
 	    c += 3;
 	}
     }
 
-  while (*c == ' ' || *c == '\t')
-    c++;
+  if (gfc_current_form == FORM_FREE)
+    {
+      while (*c == ' ' || *c == '\t')
+	c++;
+      if (gfc_wide_strncasecmp (c, "include", 7))
+	{
+	  if (!allow_continuation)
+	    return 0;
+	  for (i = 0; i < 7; ++i)
+	    {
+	      gfc_char_t c1 = gfc_wide_tolower (*c);
+	      if (c1 != (unsigned char) include[i])
+		break;
+	      c++;
+	    }
+	  if (i == 0 || *c != '&')
+	    return 0;
+	  c++;
+	  while (*c == ' ' || *c == '\t')
+	    c++;
+	  if (*c == '\0' || *c == '!')
+	    return -1;
+	  return 0;
+	}
+
+      c += 7;
+    }
+  else
+    {
+      while (*c == ' ' || *c == '\t')
+	c++;
+      if (flag_dec_include && *c == '0' && c - line == 5)
+	{
+	  c++;
+	  while (*c == ' ' || *c == '\t')
+	    c++;
+	}
+      if (c - line < 6)
+	allow_continuation = false;
+      for (i = 0; i < 7; ++i)
+	{
+	  gfc_char_t c1 = gfc_wide_tolower (*c);
+	  if (c1 != (unsigned char) include[i])
+	    break;
+	  c++;
+	  while (*c == ' ' || *c == '\t')
+	    c++;
+	}
+      if (!allow_continuation)
+	{
+	  if (i != 7)
+	    return 0;
+	}
+      else if (i != 7)
+	{
+	  if (i == 0)
+	    return 0;
 
-  if (gfc_wide_strncasecmp (c, "include", 7))
-    return false;
+	  /* At the end of line or comment this might be continued.  */
+	  if (*c == '\0' || *c == '!')
+	    return -1;
+
+	  return 0;
+	}
+    }
 
-  c += 7;
   while (*c == ' ' || *c == '\t')
     c++;
 
   /* Find filename between quotes.  */
-  
+
   quote = *c++;
   if (quote != '"' && quote != '\'')
-    return false;
+    {
+      if (allow_continuation)
+	{
+	  if (gfc_current_form == FORM_FREE)
+	    {
+	      if (quote == '&')
+		{
+		  while (*c == ' ' || *c == '\t')
+		    c++;
+		  if (*c == '\0' || *c == '!')
+		    return -1;
+		}
+	    }
+	  else if (quote == '\0' || quote == '!')
+	    return -1;
+	}
+      return 0;
+    }
 
   begin = c;
 
+  bool cont = false;
   while (*c != quote && *c != '\0')
-    c++;
+    {
+      if (allow_continuation && gfc_current_form == FORM_FREE)
+	{
+	  if (*c == '&')
+	    cont = true;
+	  else if (*c != ' ' && *c != '\t')
+	    cont = false;
+	}
+      c++;
+    }
 
   if (*c == '\0')
-    return false;
+    {
+      if (allow_continuation
+	  && (cont || gfc_current_form != FORM_FREE))
+	return -1;
+      return 0;
+    }
 
   stop = c++;
-  
+
   while (*c == ' ' || *c == '\t')
     c++;
 
   if (*c != '\0' && *c != '!')
-    return false;
+    return 0;
 
   /* We have an include line at this point.  */
 
@@ -2205,9 +2300,130 @@ include_line (gfc_char_t *line)
     exit (FATAL_EXIT_CODE);
 
   free (filename);
-  return true;
+  return 1;
 }
 
+/* Similarly, but try to parse an INCLUDE statement, using gfc_next_char etc.
+   APIs.  Return 1 if recognized as valid INCLUDE statement and load_file has
+   been called, 0 if it is not a valid INCLUDE statement and -1 if eof has
+   been encountered while parsing it.  */
+static int
+include_stmt (gfc_linebuf *b)
+{
+  int ret = 0, i, length;
+  const char *include = "include";
+  gfc_char_t c, quote = 0;
+  locus str_locus;
+  char *filename;
+
+  continue_flag = 0;
+  end_flag = 0;
+  gcc_attribute_flag = 0;
+  openmp_flag = 0;
+  openacc_flag = 0;
+  continue_count = 0;
+  continue_line = 0;
+  gfc_current_locus.lb = b;
+  gfc_current_locus.nextc = b->line;
+
+  gfc_skip_comments ();
+  gfc_gobble_whitespace ();
+
+  for (i = 0; i < 7; i++)
+    {
+      c = gfc_next_char ();
+      if (c != (unsigned char) include[i])
+	{
+	  if (gfc_current_form == FORM_FIXED
+	      && i == 0
+	      && c == '0'
+	      && gfc_current_locus.nextc == b->line + 6)
+	    {
+	      gfc_gobble_whitespace ();
+	      i--;
+	      continue;
+	    }
+	  gcc_assert (i != 0);
+	  if (c == '\n')
+	    {
+	      gfc_advance_line ();
+	      gfc_skip_comments ();
+	      if (gfc_at_eof ())
+		ret = -1;
+	    }
+	  goto do_ret;
+	}
+    }
+  gfc_gobble_whitespace ();
+
+  c = gfc_next_char ();
+  if (c == '\'' || c == '"')
+    quote = c;
+  else
+    {
+      if (c == '\n')
+	{
+	  gfc_advance_line ();
+	  gfc_skip_comments ();
+	  if (gfc_at_eof ())
+	    ret = -1;
+	}
+      goto do_ret;
+    }
+
+  str_locus = gfc_current_locus;
+  length = 0;
+  do
+    {
+      c = gfc_next_char_literal (INSTRING_NOWARN);
+      if (c == quote)
+	break;
+      if (c == '\n')
+	{
+	  gfc_advance_line ();
+	  gfc_skip_comments ();
+	  if (gfc_at_eof ())
+	    ret = -1;
+	  goto do_ret;
+	}
+      length++;
+    }
+  while (1);
+
+  gfc_gobble_whitespace ();
+  c = gfc_next_char ();
+  if (c != '\n')
+    goto do_ret;
+
+  gfc_current_locus = str_locus;
+  ret = 1;
+  filename = XNEWVEC (char, length + 1);
+  for (i = 0; i < length; i++)
+    {
+      c = gfc_next_char_literal (INSTRING_WARN);
+      gcc_assert (gfc_wide_fits_in_byte (c));
+      filename[i] = (unsigned char) c;
+    }
+  filename[length] = '\0';
+  if (!load_file (filename, NULL, false))
+    exit (FATAL_EXIT_CODE);
+
+  free (filename);
+
+do_ret:
+  continue_flag = 0;
+  end_flag = 0;
+  gcc_attribute_flag = 0;
+  openmp_flag = 0;
+  openacc_flag = 0;
+  continue_count = 0;
+  continue_line = 0;
+  memset (&gfc_current_locus, '\0', sizeof (locus));
+  memset (&openmp_locus, '\0', sizeof (locus));
+  memset (&openacc_locus, '\0', sizeof (locus));
+  memset (&gcc_attribute_locus, '\0', sizeof (locus));
+  return ret;
+}
 
 /* Load a file into memory by calling load_line until the file ends.  */
 
@@ -2215,7 +2431,7 @@ static bool
 load_file (const char *realfilename, const char *displayedname, bool initial)
 {
   gfc_char_t *line;
-  gfc_linebuf *b;
+  gfc_linebuf *b, *include_b = NULL;
   gfc_file *f;
   FILE *input;
   int len, line_len;
@@ -2318,6 +2534,7 @@ load_file (const char *realfilename, con
   for (;;)
     {
       int trunc = load_line (input, &line, &line_len, NULL);
+      int inc_line;
 
       len = gfc_wide_strlen (line);
       if (feof (input) && len == 0)
@@ -2366,11 +2583,12 @@ load_file (const char *realfilename, con
 	}
 
       /* Preprocessed files have preprocessor lines added before the byte
-         order mark, so first_line is not about the first line of the file
+	 order mark, so first_line is not about the first line of the file
 	 but the first line that's not a preprocessor line.  */
       first_line = false;
 
-      if (include_line (line))
+      inc_line = include_line (line);
+      if (inc_line > 0)
 	{
 	  current_file->line++;
 	  continue;
@@ -2403,6 +2621,36 @@ load_file (const char *realfilename, con
 
       while (file_changes_cur < file_changes_count)
 	file_changes[file_changes_cur++].lb = b;
+
+      if (flag_dec_include)
+	{
+	  if (include_b && b != include_b)
+	    {
+	      int inc_line2 = include_stmt (include_b);
+	      if (inc_line2 == 0)
+		include_b = NULL;
+	      else if (inc_line2 > 0)
+		{
+		  do
+		    {
+		      if (gfc_current_form == FORM_FIXED)
+			{
+			  for (gfc_char_t *p = include_b->line; *p; p++)
+			    *p = ' ';
+			}
+		      else
+			include_b->line[0] = '\0';
+                      if (include_b == b)
+			break;
+		      include_b = include_b->next;
+		    }
+		  while (1);
+		  include_b = NULL;
+		}
+	    }
+	  if (inc_line == -1 && !include_b)
+	    include_b = b;
+	}
     }
 
   /* Release the line buffer allocated in load_line.  */
--- gcc/testsuite/gfortran.dg/include_10.f.jj	2018-11-12 12:21:50.886637849 +0100
+++ gcc/testsuite/gfortran.dg/include_10.f	2018-11-12 12:10:22.115007990 +0100
@@ -0,0 +1,11 @@
+c { dg-do compile }
+      subroutine foo
+      implicit none
+      include 'include_10.inc'
+      i = 1
+      end subroutine foo
+      subroutine bar
+      implicit none
+      i n cl UD e'include_10.inc'
+      i = 1
+      end subroutine bar
--- gcc/testsuite/gfortran.dg/include_10.inc.jj	2018-11-12 12:21:53.946587330 +0100
+++ gcc/testsuite/gfortran.dg/include_10.inc	2018-11-12 12:07:29.694854414 +0100
@@ -0,0 +1 @@
+      integer i
--- gcc/testsuite/gfortran.dg/include_11.f.jj	2018-11-12 12:38:34.883081270 +0100
+++ gcc/testsuite/gfortran.dg/include_11.f	2018-11-12 12:38:28.239190805 +0100
@@ -0,0 +1,20 @@
+c { dg-do compile }
+      subroutine foo
+      implicit none
+c We used to accept following in fixed mode.  Shall we at least
+c warn about it?
+include 'include_10.inc'
+      i = 1
+      end subroutine foo
+      subroutine bar
+c Likewise here.
+      implicit none
+  include'include_10.inc'
+      i = 1
+      end subroutine bar
+      subroutine baz
+c And here.
+      implicit none
+     include 'include_10.inc'
+      i = 1
+      end subroutine baz
--- gcc/testsuite/gfortran.dg/include_12.f.jj	2018-11-12 14:36:42.542803497 +0100
+++ gcc/testsuite/gfortran.dg/include_12.f	2018-11-12 14:45:36.201055286 +0100
@@ -0,0 +1,49 @@
+c { dg-do compile }
+c { dg-options "-fdec-include" }
+      subroutine foo
+      implicit none
+     0include 'include_10.inc'
+      i = 1
+      end subroutine foo
+      subroutine bar
+      implicit none
+      i
+     ;n
+     +c
+                 
+c   some comment
+
+     ll
+C comment line
+     uu
+     DD
+     ee'include_10.inc'
+      i = 1
+      end subroutine bar
+      subroutine baz
+      implicit none
+     0include
+     + 'include_10.inc'
+      i = 1
+      end subroutine baz
+      subroutine qux
+      implicit none
+       i   n   C   lude                                             'inc
+* another comment line
+     &lude_10.inc'
+      i = 1
+      end subroutine qux
+       subroutine quux
+       implicit none
+     0inc
+     1lud
+     2e                                                                '
+     3include_10.inc'
+      i = 1
+      end subroutine quux
+      program include_12
+      implicit none
+      include
+! comment
+     +'include_10.inc'
+      end program
--- gcc/testsuite/gfortran.dg/include_13.f90.jj	2018-11-12 14:38:05.488443863 +0100
+++ gcc/testsuite/gfortran.dg/include_13.f90	2018-11-12 15:04:42.921254180 +0100
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+subroutine foo
+  implicit none
+  incl& ! comment1
+&u&
+       &de           &     ! comment2
+'include&
+  &_10.inc'
+  i = 1
+end subroutine foo
+subroutine bar
+  implicit none
+include &
+
+! comment3
+
+"include_10.inc"
+  i = 1
+end subroutine bar
+subroutine baz
+  implicit none
+                                  include&
+&'include_10.&
+&inc'
+  i = 1
+end subroutine baz
+subroutine qux
+  implicit none
+  include '&
+include_10.inc'
+end subroutine qux
--- gcc/testsuite/gfortran.dg/gomp/include_1.f.jj	2018-11-12 15:24:27.455829721 +0100
+++ gcc/testsuite/gfortran.dg/gomp/include_1.f	2018-11-12 15:26:02.044278080 +0100
@@ -0,0 +1,49 @@
+c { dg-do compile }
+c { dg-options "-fopenmp -fdec" }
+      subroutine foo
+      implicit none
+c$   0include 'include_1.inc'
+      i = 1
+      end subroutine foo
+      subroutine bar
+      implicit none
+      i
+C$   ;n
+     +c
+                 
+c   some comment
+
+*$   ll
+C comment line
+     uu
+     DD
+     ee'include_1.inc'
+      i = 1
+      end subroutine bar
+      subroutine baz
+      implicit none
+     0include
+     + 'include_1.inc'
+      i = 1
+      end subroutine baz
+      subroutine qux
+      implicit none
+!$     i   n   C   lude                                             'inc
+* another comment line
+     &lude_1.inc'
+      i = 1
+      end subroutine qux
+       subroutine quux
+       implicit none
+C$   0inc
+*$   1lud
+c$   2e                                                                '
+!$   3include_1.inc'
+      i = 1
+      end subroutine quux
+      program include_12
+      implicit none
+      include
+! comment
+c$   +'include_1.inc'
+      end program
--- gcc/testsuite/gfortran.dg/gomp/include_1.inc.jj	2018-11-12 15:24:30.471780253 +0100
+++ gcc/testsuite/gfortran.dg/gomp/include_1.inc	2018-11-12 12:07:29.694854414 +0100
@@ -0,0 +1 @@
+      integer i
--- gcc/testsuite/gfortran.dg/gomp/include_2.f90.jj	2018-11-12 15:24:33.556729656 +0100
+++ gcc/testsuite/gfortran.dg/gomp/include_2.f90	2018-11-12 15:26:10.480139412 +0100
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-options "-fopenmp -fdec-include" }
+subroutine foo
+  implicit none
+!$  incl& ! comment1
+!$ &u&
+!$       &de           &     ! comment2
+!$ 'include&
+  &_1.inc'
+  i = 1
+end subroutine foo
+subroutine bar
+  implicit none
+!$ include &
+
+! comment3
+
+!$ "include_1.inc"
+  i = 1
+end subroutine bar
+subroutine baz
+  implicit none
+!$                                  include&
+!$ &'include_1.&
+!$ &inc'
+  i = 1
+end subroutine baz
+subroutine qux
+  implicit none
+!$  include '&
+include_1.inc'
+end subroutine qux

	Jakub

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

* Re: [PATCH] Fortran include line fixes and -fdec-include support
  2018-11-12 14:51 [PATCH] Fortran include line fixes and -fdec-include support Jakub Jelinek
@ 2018-11-12 23:25 ` Fritz Reese
  2018-11-13 10:06 ` Mark Eggleston
  2018-11-20 17:02 ` Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support) Jakub Jelinek
  2 siblings, 0 replies; 11+ messages in thread
From: Fritz Reese @ 2018-11-12 23:25 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran, mark.eggleston, Jeff Law

On Mon, Nov 12, 2018 at 9:51 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> In fortran97.pdf I read:
> "Except in a character context, blanks are insignificant and may be used freely throughout the program."
> and while we handle that in most cases, we don't allow spaces in INCLUDE
> lines in fixed form, while e.g. ifort does.

I agree with fixing this unconditionally.

> Another thing, which I haven't touched in the PR except covering it with a
> testcase is that we allow INLINE line in fixed form to start even in columns
> 1 to 6, while ifort rejects that.  Is say
>      include 'omp_lib.h'
> valid in fixed form?  i in column 6 normally means a continuation line,
> though not sure if anything can in a valid program contain nclude
> followed by character literal.  Shall we reject that, or at least warn that
> it won't be portable?

AFAICT this is unambiguous so I would certainly suggest adding such a
warning (enabled by default).

> The last thing, biggest part of the patch, is that for legacy DEC
> compatibility, the DEC manuals document INCLUDE as a statement, not a line,
> [...]
> This means there can be (as can be seen in the following testcases)
> continuations in both forms, and in fixed form there can be 0 in column 6.

Makes sense to me. I concur with adding -fdec-include to support this
under -fdec.

If we are going to warn for the above and re-do the include matching
anyway, I wonder if we should have also a specific error message for a
labeled include statement? For example,

10    include 'include_10.inc'

Will result in the generic 'Unclassifiable statement' error, but ifort
gives "Label on INCLUDE is invalid."

> In order not to duplicate all the handling of continuations, comment
> skipping etc., the patch just adjusts the include_line routine so that it
> signals if the current line is a possible start of a valid INCLUDE statement
> when in -fdec-include mode, and if so, whenever it reads a further line it
> retries to parse it using
> gfc_next_char/gfc_next_char_literal/gfc_gobble_whitespace APIs as an INCLUDE
> stmt.  If it is found not to be a valid INCLUDE statement line or set of
> lines, it returns 0, if it is valid, it returns 1 together with load_file
> like include_line does and clears all the lines containint the INCLUDE
> statement.  If the reading stops because we don't have enough lines, -1 is
> returned and the caller tries again with more lines.

LGTM.

> In addition to the above mentioned question about include in columns 1-6 in
> fixed form, another thing is that we support
>       print *, 'abc''def'
>       print *, "hij""klm"
> which prints abc'def and hij"klm.  Shall we support that for INCLUDE lines
> and INCLUDE statements too?

It appears ifort does also support this. I see no reason not to, as
the feature should be straightforward to implement.

> Tested on x86_64-linux, ok for trunk if it passes full bootstrap/regtest?

With the above additions it looks ok to me, but I must defer to an
official Fortran reviewer.

---
Fritz

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

* Re: [PATCH] Fortran include line fixes and -fdec-include support
  2018-11-12 14:51 [PATCH] Fortran include line fixes and -fdec-include support Jakub Jelinek
  2018-11-12 23:25 ` Fritz Reese
@ 2018-11-13 10:06 ` Mark Eggleston
  2018-11-13 10:53   ` Jakub Jelinek
  2018-11-20 17:02 ` Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support) Jakub Jelinek
  2 siblings, 1 reply; 11+ messages in thread
From: Mark Eggleston @ 2018-11-13 10:06 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches, fortran; +Cc: Jeff Law

Jakub,

I've applied this patch and tried it out.

The following fail to compile:

In free form with or without the optional initial & on the continuation 
line:

subroutine one()
   include &
   &"include_4.inc'
   integer(i4) :: i
end subroutine one

In fixed form:

       subroutine one()
       integer include
       include
      +"include_16.inc'
       write (*,*) include
       end subroutine one

Both give "Error: Unclassifiable statement at (1)" with 1 at the start 
of the include line.

These cases are not covered by the test cases in the patch.

Is there any particular reason that include line continuation is 
isolated in -fdec-include? Is there a specific restriction regarding 
include lines in the Fortran standard such that continuations in free 
form and fixed form can't be used with include lines?

regards,

Mark Eggleston

On 12/11/2018 14:51, Jakub Jelinek wrote:
> Hi!
>
> In fortran97.pdf I read:
> "Except in a character context, blanks are insignificant and may be used freely throughout the program."
> and while we handle that in most cases, we don't allow spaces in INCLUDE
> lines in fixed form, while e.g. ifort does.
>
> Another thing, which I haven't touched in the PR except covering it with a
> testcase is that we allow INLINE line in fixed form to start even in columns
> 1 to 6, while ifort rejects that.  Is say
>       include 'omp_lib.h'
> valid in fixed form?  i in column 6 normally means a continuation line,
> though not sure if anything can in a valid program contain nclude
> followed by character literal.  Shall we reject that, or at least warn that
> it won't be portable?
>
> The last thing, biggest part of the patch, is that for legacy DEC
> compatibility, the DEC manuals document INCLUDE as a statement, not a line,
> the
> "An INCLUDE line is not a Fortran statement."
> and
> "An INCLUDE line shall appear on a single source line where a statement may appear; it shall be
> the only nonblank text on this line other than an optional trailing comment. Thus, a statement
> label is not allowed."
> bullets don't apply, but instead there is:
> "The INCLUDE statement takes one of the following forms:"
> "An INCLUDE statement can appear anywhere within a scoping unit. The statement
> can span more than one source line, but no other statement can appear on the same
> line. The source line cannot be labeled."
>
> This means there can be (as can be seen in the following testcases)
> continuations in both forms, and in fixed form there can be 0 in column 6.
>
> In order not to duplicate all the handling of continuations, comment
> skipping etc., the patch just adjusts the include_line routine so that it
> signals if the current line is a possible start of a valid INCLUDE statement
> when in -fdec-include mode, and if so, whenever it reads a further line it
> retries to parse it using
> gfc_next_char/gfc_next_char_literal/gfc_gobble_whitespace APIs as an INCLUDE
> stmt.  If it is found not to be a valid INCLUDE statement line or set of
> lines, it returns 0, if it is valid, it returns 1 together with load_file
> like include_line does and clears all the lines containint the INCLUDE
> statement.  If the reading stops because we don't have enough lines, -1 is
> returned and the caller tries again with more lines.
>
> Tested on x86_64-linux, ok for trunk if it passes full bootstrap/regtest?
>
> In addition to the above mentioned question about include in columns 1-6 in
> fixed form, another thing is that we support
>        print *, 'abc''def'
>        print *, "hij""klm"
> which prints abc'def and hij"klm.  Shall we support that for INCLUDE lines
> and INCLUDE statements too?
>
> 2018-11-12  Jakub Jelinek  <jakub@redhat.com>
> 	    Mark Eggleston  <mark.eggleston@codethink.com>
>
> 	* lang.opt (fdec-include): New option.
> 	* options.c (set_dec_flags): Set also flag_dec_include.
> 	* scanner.c (include_line): Change return type from bool to int.
> 	In fixed form allow spaces in between include keyword letters.
> 	For -fdec-include, allow in fixed form 0 in column 6.  With
> 	-fdec-include return -1 if the parsed line is not full include
> 	statement and it could be successfully completed on continuation
> 	lines.
> 	(include_stmt): New function.
> 	(load_file): Adjust include_line caller.  If it returns -1, keep
> 	trying include_stmt until it stops returning -1 whenever adding
> 	further line of input.
>
> 	* gfortran.dg/include_10.f: New test.
> 	* gfortran.dg/include_10.inc: New file.
> 	* gfortran.dg/include_11.f: New test.
> 	* gfortran.dg/include_12.f: New test.
> 	* gfortran.dg/include_13.f90: New test.
> 	* gfortran.dg/gomp/include_1.f: New test.
> 	* gfortran.dg/gomp/include_1.inc: New file.
> 	* gfortran.dg/gomp/include_2.f90: New test.
>
> --- gcc/fortran/lang.opt.jj	2018-07-18 22:57:15.227785894 +0200
> +++ gcc/fortran/lang.opt	2018-11-12 09:35:03.185259773 +0100
> @@ -440,6 +440,10 @@ fdec
>   Fortran Var(flag_dec)
>   Enable all DEC language extensions.
>   
> +fdec-include
> +Fortran Var(flag_dec_include)
> +Enable legacy parsing of INCLUDE as statement.
> +
>   fdec-intrinsic-ints
>   Fortran Var(flag_dec_intrinsic_ints)
>   Enable kind-specific variants of integer intrinsic functions.
> --- gcc/fortran/options.c.jj	2018-11-06 18:27:13.828831733 +0100
> +++ gcc/fortran/options.c	2018-11-12 09:35:39.515655453 +0100
> @@ -68,6 +68,7 @@ set_dec_flags (int value)
>     flag_dec_intrinsic_ints |= value;
>     flag_dec_static |= value;
>     flag_dec_math |= value;
> +  flag_dec_include |= value;
>   }
>   
>   
> --- gcc/fortran/scanner.c.jj	2018-05-08 13:56:41.691932534 +0200
> +++ gcc/fortran/scanner.c	2018-11-12 15:21:51.249391936 +0100
> @@ -2135,14 +2135,18 @@ static bool load_file (const char *, con
>   /* include_line()-- Checks a line buffer to see if it is an include
>      line.  If so, we call load_file() recursively to load the included
>      file.  We never return a syntax error because a statement like
> -   "include = 5" is perfectly legal.  We return false if no include was
> -   processed or true if we matched an include.  */
> +   "include = 5" is perfectly legal.  We return 0 if no include was
> +   processed, 1 if we matched an include or -1 if include was
> +   partially processed, but will need continuation lines.  */
>   
> -static bool
> +static int
>   include_line (gfc_char_t *line)
>   {
>     gfc_char_t quote, *c, *begin, *stop;
>     char *filename;
> +  const char *include = "include";
> +  bool allow_continuation = flag_dec_include;
> +  int i;
>   
>     c = line;
>   
> @@ -2158,42 +2162,133 @@ include_line (gfc_char_t *line)
>         else
>   	{
>   	  if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
> -	      && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
> +	      && c[1] == '$' && c[2] == ' ')
>   	    c += 3;
>   	}
>       }
>   
> -  while (*c == ' ' || *c == '\t')
> -    c++;
> +  if (gfc_current_form == FORM_FREE)
> +    {
> +      while (*c == ' ' || *c == '\t')
> +	c++;
> +      if (gfc_wide_strncasecmp (c, "include", 7))
> +	{
> +	  if (!allow_continuation)
> +	    return 0;
> +	  for (i = 0; i < 7; ++i)
> +	    {
> +	      gfc_char_t c1 = gfc_wide_tolower (*c);
> +	      if (c1 != (unsigned char) include[i])
> +		break;
> +	      c++;
> +	    }
> +	  if (i == 0 || *c != '&')
> +	    return 0;
> +	  c++;
> +	  while (*c == ' ' || *c == '\t')
> +	    c++;
> +	  if (*c == '\0' || *c == '!')
> +	    return -1;
> +	  return 0;
> +	}
> +
> +      c += 7;
> +    }
> +  else
> +    {
> +      while (*c == ' ' || *c == '\t')
> +	c++;
> +      if (flag_dec_include && *c == '0' && c - line == 5)
> +	{
> +	  c++;
> +	  while (*c == ' ' || *c == '\t')
> +	    c++;
> +	}
> +      if (c - line < 6)
> +	allow_continuation = false;
> +      for (i = 0; i < 7; ++i)
> +	{
> +	  gfc_char_t c1 = gfc_wide_tolower (*c);
> +	  if (c1 != (unsigned char) include[i])
> +	    break;
> +	  c++;
> +	  while (*c == ' ' || *c == '\t')
> +	    c++;
> +	}
> +      if (!allow_continuation)
> +	{
> +	  if (i != 7)
> +	    return 0;
> +	}
> +      else if (i != 7)
> +	{
> +	  if (i == 0)
> +	    return 0;
>   
> -  if (gfc_wide_strncasecmp (c, "include", 7))
> -    return false;
> +	  /* At the end of line or comment this might be continued.  */
> +	  if (*c == '\0' || *c == '!')
> +	    return -1;
> +
> +	  return 0;
> +	}
> +    }
>   
> -  c += 7;
>     while (*c == ' ' || *c == '\t')
>       c++;
>   
>     /* Find filename between quotes.  */
> -
> +
>     quote = *c++;
>     if (quote != '"' && quote != '\'')
> -    return false;
> +    {
> +      if (allow_continuation)
> +	{
> +	  if (gfc_current_form == FORM_FREE)
> +	    {
> +	      if (quote == '&')
> +		{
> +		  while (*c == ' ' || *c == '\t')
> +		    c++;
> +		  if (*c == '\0' || *c == '!')
> +		    return -1;
> +		}
> +	    }
> +	  else if (quote == '\0' || quote == '!')
> +	    return -1;
> +	}
> +      return 0;
> +    }
>   
>     begin = c;
>   
> +  bool cont = false;
>     while (*c != quote && *c != '\0')
> -    c++;
> +    {
> +      if (allow_continuation && gfc_current_form == FORM_FREE)
> +	{
> +	  if (*c == '&')
> +	    cont = true;
> +	  else if (*c != ' ' && *c != '\t')
> +	    cont = false;
> +	}
> +      c++;
> +    }
>   
>     if (*c == '\0')
> -    return false;
> +    {
> +      if (allow_continuation
> +	  && (cont || gfc_current_form != FORM_FREE))
> +	return -1;
> +      return 0;
> +    }
>   
>     stop = c++;
> -
> +
>     while (*c == ' ' || *c == '\t')
>       c++;
>   
>     if (*c != '\0' && *c != '!')
> -    return false;
> +    return 0;
>   
>     /* We have an include line at this point.  */
>   
> @@ -2205,9 +2300,130 @@ include_line (gfc_char_t *line)
>       exit (FATAL_EXIT_CODE);
>   
>     free (filename);
> -  return true;
> +  return 1;
>   }
>   
> +/* Similarly, but try to parse an INCLUDE statement, using gfc_next_char etc.
> +   APIs.  Return 1 if recognized as valid INCLUDE statement and load_file has
> +   been called, 0 if it is not a valid INCLUDE statement and -1 if eof has
> +   been encountered while parsing it.  */
> +static int
> +include_stmt (gfc_linebuf *b)
> +{
> +  int ret = 0, i, length;
> +  const char *include = "include";
> +  gfc_char_t c, quote = 0;
> +  locus str_locus;
> +  char *filename;
> +
> +  continue_flag = 0;
> +  end_flag = 0;
> +  gcc_attribute_flag = 0;
> +  openmp_flag = 0;
> +  openacc_flag = 0;
> +  continue_count = 0;
> +  continue_line = 0;
> +  gfc_current_locus.lb = b;
> +  gfc_current_locus.nextc = b->line;
> +
> +  gfc_skip_comments ();
> +  gfc_gobble_whitespace ();
> +
> +  for (i = 0; i < 7; i++)
> +    {
> +      c = gfc_next_char ();
> +      if (c != (unsigned char) include[i])
> +	{
> +	  if (gfc_current_form == FORM_FIXED
> +	      && i == 0
> +	      && c == '0'
> +	      && gfc_current_locus.nextc == b->line + 6)
> +	    {
> +	      gfc_gobble_whitespace ();
> +	      i--;
> +	      continue;
> +	    }
> +	  gcc_assert (i != 0);
> +	  if (c == '\n')
> +	    {
> +	      gfc_advance_line ();
> +	      gfc_skip_comments ();
> +	      if (gfc_at_eof ())
> +		ret = -1;
> +	    }
> +	  goto do_ret;
> +	}
> +    }
> +  gfc_gobble_whitespace ();
> +
> +  c = gfc_next_char ();
> +  if (c == '\'' || c == '"')
> +    quote = c;
> +  else
> +    {
> +      if (c == '\n')
> +	{
> +	  gfc_advance_line ();
> +	  gfc_skip_comments ();
> +	  if (gfc_at_eof ())
> +	    ret = -1;
> +	}
> +      goto do_ret;
> +    }
> +
> +  str_locus = gfc_current_locus;
> +  length = 0;
> +  do
> +    {
> +      c = gfc_next_char_literal (INSTRING_NOWARN);
> +      if (c == quote)
> +	break;
> +      if (c == '\n')
> +	{
> +	  gfc_advance_line ();
> +	  gfc_skip_comments ();
> +	  if (gfc_at_eof ())
> +	    ret = -1;
> +	  goto do_ret;
> +	}
> +      length++;
> +    }
> +  while (1);
> +
> +  gfc_gobble_whitespace ();
> +  c = gfc_next_char ();
> +  if (c != '\n')
> +    goto do_ret;
> +
> +  gfc_current_locus = str_locus;
> +  ret = 1;
> +  filename = XNEWVEC (char, length + 1);
> +  for (i = 0; i < length; i++)
> +    {
> +      c = gfc_next_char_literal (INSTRING_WARN);
> +      gcc_assert (gfc_wide_fits_in_byte (c));
> +      filename[i] = (unsigned char) c;
> +    }
> +  filename[length] = '\0';
> +  if (!load_file (filename, NULL, false))
> +    exit (FATAL_EXIT_CODE);
> +
> +  free (filename);
> +
> +do_ret:
> +  continue_flag = 0;
> +  end_flag = 0;
> +  gcc_attribute_flag = 0;
> +  openmp_flag = 0;
> +  openacc_flag = 0;
> +  continue_count = 0;
> +  continue_line = 0;
> +  memset (&gfc_current_locus, '\0', sizeof (locus));
> +  memset (&openmp_locus, '\0', sizeof (locus));
> +  memset (&openacc_locus, '\0', sizeof (locus));
> +  memset (&gcc_attribute_locus, '\0', sizeof (locus));
> +  return ret;
> +}
>   
>   /* Load a file into memory by calling load_line until the file ends.  */
>   
> @@ -2215,7 +2431,7 @@ static bool
>   load_file (const char *realfilename, const char *displayedname, bool initial)
>   {
>     gfc_char_t *line;
> -  gfc_linebuf *b;
> +  gfc_linebuf *b, *include_b = NULL;
>     gfc_file *f;
>     FILE *input;
>     int len, line_len;
> @@ -2318,6 +2534,7 @@ load_file (const char *realfilename, con
>     for (;;)
>       {
>         int trunc = load_line (input, &line, &line_len, NULL);
> +      int inc_line;
>   
>         len = gfc_wide_strlen (line);
>         if (feof (input) && len == 0)
> @@ -2366,11 +2583,12 @@ load_file (const char *realfilename, con
>   	}
>   
>         /* Preprocessed files have preprocessor lines added before the byte
> -         order mark, so first_line is not about the first line of the file
> +	 order mark, so first_line is not about the first line of the file
>   	 but the first line that's not a preprocessor line.  */
>         first_line = false;
>   
> -      if (include_line (line))
> +      inc_line = include_line (line);
> +      if (inc_line > 0)
>   	{
>   	  current_file->line++;
>   	  continue;
> @@ -2403,6 +2621,36 @@ load_file (const char *realfilename, con
>   
>         while (file_changes_cur < file_changes_count)
>   	file_changes[file_changes_cur++].lb = b;
> +
> +      if (flag_dec_include)
> +	{
> +	  if (include_b && b != include_b)
> +	    {
> +	      int inc_line2 = include_stmt (include_b);
> +	      if (inc_line2 == 0)
> +		include_b = NULL;
> +	      else if (inc_line2 > 0)
> +		{
> +		  do
> +		    {
> +		      if (gfc_current_form == FORM_FIXED)
> +			{
> +			  for (gfc_char_t *p = include_b->line; *p; p++)
> +			    *p = ' ';
> +			}
> +		      else
> +			include_b->line[0] = '\0';
> +                      if (include_b == b)
> +			break;
> +		      include_b = include_b->next;
> +		    }
> +		  while (1);
> +		  include_b = NULL;
> +		}
> +	    }
> +	  if (inc_line == -1 && !include_b)
> +	    include_b = b;
> +	}
>       }
>   
>     /* Release the line buffer allocated in load_line.  */
> --- gcc/testsuite/gfortran.dg/include_10.f.jj	2018-11-12 12:21:50.886637849 +0100
> +++ gcc/testsuite/gfortran.dg/include_10.f	2018-11-12 12:10:22.115007990 +0100
> @@ -0,0 +1,11 @@
> +c { dg-do compile }
> +      subroutine foo
> +      implicit none
> +      include 'include_10.inc'
> +      i = 1
> +      end subroutine foo
> +      subroutine bar
> +      implicit none
> +      i n cl UD e'include_10.inc'
> +      i = 1
> +      end subroutine bar
> --- gcc/testsuite/gfortran.dg/include_10.inc.jj	2018-11-12 12:21:53.946587330 +0100
> +++ gcc/testsuite/gfortran.dg/include_10.inc	2018-11-12 12:07:29.694854414 +0100
> @@ -0,0 +1 @@
> +      integer i
> --- gcc/testsuite/gfortran.dg/include_11.f.jj	2018-11-12 12:38:34.883081270 +0100
> +++ gcc/testsuite/gfortran.dg/include_11.f	2018-11-12 12:38:28.239190805 +0100
> @@ -0,0 +1,20 @@
> +c { dg-do compile }
> +      subroutine foo
> +      implicit none
> +c We used to accept following in fixed mode.  Shall we at least
> +c warn about it?
> +include 'include_10.inc'
> +      i = 1
> +      end subroutine foo
> +      subroutine bar
> +c Likewise here.
> +      implicit none
> +  include'include_10.inc'
> +      i = 1
> +      end subroutine bar
> +      subroutine baz
> +c And here.
> +      implicit none
> +     include 'include_10.inc'
> +      i = 1
> +      end subroutine baz
> --- gcc/testsuite/gfortran.dg/include_12.f.jj	2018-11-12 14:36:42.542803497 +0100
> +++ gcc/testsuite/gfortran.dg/include_12.f	2018-11-12 14:45:36.201055286 +0100
> @@ -0,0 +1,49 @@
> +c { dg-do compile }
> +c { dg-options "-fdec-include" }
> +      subroutine foo
> +      implicit none
> +     0include 'include_10.inc'
> +      i = 1
> +      end subroutine foo
> +      subroutine bar
> +      implicit none
> +      i
> +     ;n
> +     +c
> +
> +c   some comment
> +
> +     ll
> +C comment line
> +     uu
> +     DD
> +     ee'include_10.inc'
> +      i = 1
> +      end subroutine bar
> +      subroutine baz
> +      implicit none
> +     0include
> +     + 'include_10.inc'
> +      i = 1
> +      end subroutine baz
> +      subroutine qux
> +      implicit none
> +       i   n   C   lude                                             'inc
> +* another comment line
> +     &lude_10.inc'
> +      i = 1
> +      end subroutine qux
> +       subroutine quux
> +       implicit none
> +     0inc
> +     1lud
> +     2e                                                                '
> +     3include_10.inc'
> +      i = 1
> +      end subroutine quux
> +      program include_12
> +      implicit none
> +      include
> +! comment
> +     +'include_10.inc'
> +      end program
> --- gcc/testsuite/gfortran.dg/include_13.f90.jj	2018-11-12 14:38:05.488443863 +0100
> +++ gcc/testsuite/gfortran.dg/include_13.f90	2018-11-12 15:04:42.921254180 +0100
> @@ -0,0 +1,32 @@
> +! { dg-do compile }
> +! { dg-options "-fdec" }
> +subroutine foo
> +  implicit none
> +  incl& ! comment1
> +&u&
> +       &de           &     ! comment2
> +'include&
> +  &_10.inc'
> +  i = 1
> +end subroutine foo
> +subroutine bar
> +  implicit none
> +include &
> +
> +! comment3
> +
> +"include_10.inc"
> +  i = 1
> +end subroutine bar
> +subroutine baz
> +  implicit none
> +                                  include&
> +&'include_10.&
> +&inc'
> +  i = 1
> +end subroutine baz
> +subroutine qux
> +  implicit none
> +  include '&
> +include_10.inc'
> +end subroutine qux
> --- gcc/testsuite/gfortran.dg/gomp/include_1.f.jj	2018-11-12 15:24:27.455829721 +0100
> +++ gcc/testsuite/gfortran.dg/gomp/include_1.f	2018-11-12 15:26:02.044278080 +0100
> @@ -0,0 +1,49 @@
> +c { dg-do compile }
> +c { dg-options "-fopenmp -fdec" }
> +      subroutine foo
> +      implicit none
> +c$   0include 'include_1.inc'
> +      i = 1
> +      end subroutine foo
> +      subroutine bar
> +      implicit none
> +      i
> +C$   ;n
> +     +c
> +
> +c   some comment
> +
> +*$   ll
> +C comment line
> +     uu
> +     DD
> +     ee'include_1.inc'
> +      i = 1
> +      end subroutine bar
> +      subroutine baz
> +      implicit none
> +     0include
> +     + 'include_1.inc'
> +      i = 1
> +      end subroutine baz
> +      subroutine qux
> +      implicit none
> +!$     i   n   C   lude                                             'inc
> +* another comment line
> +     &lude_1.inc'
> +      i = 1
> +      end subroutine qux
> +       subroutine quux
> +       implicit none
> +C$   0inc
> +*$   1lud
> +c$   2e                                                                '
> +!$   3include_1.inc'
> +      i = 1
> +      end subroutine quux
> +      program include_12
> +      implicit none
> +      include
> +! comment
> +c$   +'include_1.inc'
> +      end program
> --- gcc/testsuite/gfortran.dg/gomp/include_1.inc.jj	2018-11-12 15:24:30.471780253 +0100
> +++ gcc/testsuite/gfortran.dg/gomp/include_1.inc	2018-11-12 12:07:29.694854414 +0100
> @@ -0,0 +1 @@
> +      integer i
> --- gcc/testsuite/gfortran.dg/gomp/include_2.f90.jj	2018-11-12 15:24:33.556729656 +0100
> +++ gcc/testsuite/gfortran.dg/gomp/include_2.f90	2018-11-12 15:26:10.480139412 +0100
> @@ -0,0 +1,32 @@
> +! { dg-do compile }
> +! { dg-options "-fopenmp -fdec-include" }
> +subroutine foo
> +  implicit none
> +!$  incl& ! comment1
> +!$ &u&
> +!$       &de           &     ! comment2
> +!$ 'include&
> +  &_1.inc'
> +  i = 1
> +end subroutine foo
> +subroutine bar
> +  implicit none
> +!$ include &
> +
> +! comment3
> +
> +!$ "include_1.inc"
> +  i = 1
> +end subroutine bar
> +subroutine baz
> +  implicit none
> +!$                                  include&
> +!$ &'include_1.&
> +!$ &inc'
> +  i = 1
> +end subroutine baz
> +subroutine qux
> +  implicit none
> +!$  include '&
> +include_1.inc'
> +end subroutine qux
>
> 	Jakub
>
-- 
https://www.codethink.co.uk/privacy.html

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

* Re: [PATCH] Fortran include line fixes and -fdec-include support
  2018-11-13 10:06 ` Mark Eggleston
@ 2018-11-13 10:53   ` Jakub Jelinek
  0 siblings, 0 replies; 11+ messages in thread
From: Jakub Jelinek @ 2018-11-13 10:53 UTC (permalink / raw)
  To: Mark Eggleston; +Cc: gcc-patches, fortran, Jeff Law

On Tue, Nov 13, 2018 at 10:06:39AM +0000, Mark Eggleston wrote:
> I've applied this patch and tried it out.
> 
> The following fail to compile:

That is IMHO correct, it fails to compile with ifort as well:
https://fortran.godbolt.org/z/Aav6dv

The problem is in mixing quotes, " vs. '
If I fix that, it works (changed the testcases to use the include file
I had in the patch):

! { dg-do compile }
! { dg-options "-fdec" }
subroutine quux
  implicit none
  include &
  &'include_10.inc'
  i = 1
end subroutine quux
subroutine quuz
  implicit none
  include &
  &"include_10.inc"
  i = 1
end subroutine quuz

c { dg-do compile }
c { dg-options "-fdec-include" }
      subroutine quuz
      implicit none
      integer include
      include
     +"include_10.inc"
      i = 1
      include
     + = 2
      write (*,*) include
      end subroutine quuz
      subroutine corge
      implicit none
      include
     +'include_10.inc'
      i = 1
      end subroutine corge

both compile.  I can include these snippets into the testcases.

> Is there any particular reason that include line continuation is isolated in
> -fdec-include? Is there a specific restriction regarding include lines in
> the Fortran standard such that continuations in free form and fixed form
> can't be used with include lines?

My reading of the Fortran standard says it is invalid, but I am not a good
Fortran language lawyer, so I'm open to be convinced otherwise.

The two bullets that I think say it are:
"An INCLUDE line is not a Fortran statement."
and
"An INCLUDE line shall appear on a single source line where a statement may appear; it shall be
the only nonblank text on this line other than an optional trailing comment. Thus, a statement
label is not allowed."

If there are continuations, it is not a single source line anymore, I don't
see anywhere a word that all the continuations together with the initial
source line are considered a single source line for the purposes of the rest
of the standard.

And in the DEC manual, it explicitly says that INCLUDE is a statement and
that it can be continued.

	Jakub

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

* Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2018-11-12 14:51 [PATCH] Fortran include line fixes and -fdec-include support Jakub Jelinek
  2018-11-12 23:25 ` Fritz Reese
  2018-11-13 10:06 ` Mark Eggleston
@ 2018-11-20 17:02 ` Jakub Jelinek
  2018-11-21  7:31   ` Thomas Koenig
  2 siblings, 1 reply; 11+ messages in thread
From: Jakub Jelinek @ 2018-11-20 17:02 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Mark Eggleston, Jeff Law

Hi!

I'd like to ping this patch, ok for trunk?

> 2018-11-12  Jakub Jelinek  <jakub@redhat.com>
> 	    Mark Eggleston  <mark.eggleston@codethink.com>
> 
> 	* lang.opt (fdec-include): New option.
> 	* options.c (set_dec_flags): Set also flag_dec_include.
> 	* scanner.c (include_line): Change return type from bool to int.
> 	In fixed form allow spaces in between include keyword letters.
> 	For -fdec-include, allow in fixed form 0 in column 6.  With
> 	-fdec-include return -1 if the parsed line is not full include
> 	statement and it could be successfully completed on continuation
> 	lines.
> 	(include_stmt): New function.
> 	(load_file): Adjust include_line caller.  If it returns -1, keep
> 	trying include_stmt until it stops returning -1 whenever adding
> 	further line of input.
> 
> 	* gfortran.dg/include_10.f: New test.
> 	* gfortran.dg/include_10.inc: New file.
> 	* gfortran.dg/include_11.f: New test.
> 	* gfortran.dg/include_12.f: New test.
> 	* gfortran.dg/include_13.f90: New test.
> 	* gfortran.dg/gomp/include_1.f: New test.
> 	* gfortran.dg/gomp/include_1.inc: New file.
> 	* gfortran.dg/gomp/include_2.f90: New test.

	Jakub

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2018-11-20 17:02 ` Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support) Jakub Jelinek
@ 2018-11-21  7:31   ` Thomas Koenig
  2018-11-21  8:25     ` Jakub Jelinek
  0 siblings, 1 reply; 11+ messages in thread
From: Thomas Koenig @ 2018-11-21  7:31 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches, fortran; +Cc: Mark Eggleston, Jeff Law

Hi Jakub,

> I'd like to ping this patch, ok for trunk?

OK. Thanks for the patch!

Before 9.0 is released, we should also document the flag
(and the extension it supports) in the manual, and note it
in changes.html and on the Wiki.  Would you also do that?

Regards

	Thomas

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2018-11-21  7:31   ` Thomas Koenig
@ 2018-11-21  8:25     ` Jakub Jelinek
  2018-11-21 19:31       ` Thomas Koenig
  2019-01-19 22:49       ` Gerald Pfeifer
  0 siblings, 2 replies; 11+ messages in thread
From: Jakub Jelinek @ 2018-11-21  8:25 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: gcc-patches, fortran, Mark Eggleston, Jeff Law

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

On Wed, Nov 21, 2018 at 08:31:17AM +0100, Thomas Koenig wrote:
> > I'd like to ping this patch, ok for trunk?
> 
> OK. Thanks for the patch!

Thanks.

> Before 9.0 is released, we should also document the flag
> (and the extension it supports) in the manual, and note it
> in changes.html and on the Wiki.  Would you also do that?

Like this?  Ok for trunk/wwwdocs?

2018-11-21  Jakub Jelinek  <jakub@redhat.com>

	* invoke.texi (-fdec-include): Document.

--- gcc/fortran/invoke.texi.jj	2018-08-26 22:42:19.907823618 +0200
+++ gcc/fortran/invoke.texi	2018-11-21 09:14:21.449174232 +0100
@@ -119,7 +119,7 @@ by type.  Explanations are in the follow
 @gccoptlist{-fall-intrinsics -fbackslash -fcray-pointer -fd-lines-as-code @gol
 -fd-lines-as-comments @gol
 -fdec -fdec-structure -fdec-intrinsic-ints -fdec-static -fdec-math @gol
--fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 @gol
+-fdec-include -fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 @gol
 -fdefault-real-10 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
 -ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
@@ -277,6 +277,12 @@ functions (e.g. TAND, ATAND, etc...) for
 Enable DEC-style STATIC and AUTOMATIC attributes to explicitly specify
 the storage of variables and other objects.
 
+@item -fdec-include
+@opindex @code{fdec-include}
+Enable parsing of INCLUDE as a statement in addition to parsing it as
+INCLUDE line.  When parsed as INCLUDE statement, INCLUDE does not have to
+be on a single line and can use line continuations.
+
 @item -fdollar-ok
 @opindex @code{fdollar-ok}
 @cindex @code{$}


	Jakub

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

--- gcc-9/changes.html.jj	2018-11-14 17:46:10.747799079 +0100
+++ gcc-9/changes.html	2018-11-21 09:23:48.974896385 +0100
@@ -118,6 +118,14 @@ a work-in-progress.</p>
   the <code>IEEE_IS_NAN</code> function from the intrinsic
   module <code>IEEE_ARITHMETIC</code>.
   </li>
+  <li>
+    A new command line option <code>-fdec-include</code>, set also
+    by <code>-fdec</code> option, has been added for an extension
+    for compatibility with legacy code.  With this option,
+    <code>INCLUDE</code> directive is parsed also as a statement,
+    which allows the directive to be written on multiple source lines
+    with line continuations.
+  </li>
 </ul>
 
 <!-- <h3 id="go">Go</h3> -->

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2018-11-21  8:25     ` Jakub Jelinek
@ 2018-11-21 19:31       ` Thomas Koenig
  2019-01-19 22:49       ` Gerald Pfeifer
  1 sibling, 0 replies; 11+ messages in thread
From: Thomas Koenig @ 2018-11-21 19:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran, Mark Eggleston, Jeff Law

Hi Jakub,

>> Before 9.0 is released, we should also document the flag
>> (and the extension it supports) in the manual, and note it
>> in changes.html and on the Wiki.  Would you also do that?
> Like this?  Ok for trunk/wwwdocs?

OK for trunk (and I don't think you need my OK for wwwdocs, but
you have it anyway :-)

Regards

	Thomas

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2018-11-21  8:25     ` Jakub Jelinek
  2018-11-21 19:31       ` Thomas Koenig
@ 2019-01-19 22:49       ` Gerald Pfeifer
  2019-01-19 22:52         ` Jakub Jelinek
  1 sibling, 1 reply; 11+ messages in thread
From: Gerald Pfeifer @ 2019-01-19 22:49 UTC (permalink / raw)
  To: Jakub Jelinek, fortran
  Cc: Thomas Koenig, gcc-patches, Mark Eggleston, Jeff Law

Hej Jakub, hej Fortran hackers,

On Wed, 21 Nov 2018, Jakub Jelinek wrote:
> Like this?  Ok for trunk/wwwdocs?
> 
> 2018-11-21  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* invoke.texi (-fdec-include): Document.

how about the refinement below?

Gerald

Index: gcc-9/changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/changes.html,v
retrieving revision 1.33
diff -u -r1.33 changes.html
--- gcc-9/changes.html	11 Jan 2019 19:10:28 -0000	1.33
+++ gcc-9/changes.html	19 Jan 2019 22:48:22 -0000
@@ -170,12 +170,12 @@
   module <code>IEEE_ARITHMETIC</code>.
   </li>
   <li>
-    A new command line option <code>-fdec-include</code>, set also
-    by <code>-fdec</code> option, has been added for an extension
-    for compatibility with legacy code.  With this option,
-    <code>INCLUDE</code> directive is parsed also as a statement,
-    which allows the directive to be written on multiple source lines
-    with line continuations.
+    A new command-line option <code>-fdec-include</code>, set also
+    by the <code>-fdec</code> option, has been added to increase
+    compatibility with legacy code.  With this option, an
+    <code>INCLUDE</code> directive is also parsed as a statement,
+    which allows the directive to be spread across multiple source
+    lines with line continuations.
   </li>
 </ul>
 

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2019-01-19 22:49       ` Gerald Pfeifer
@ 2019-01-19 22:52         ` Jakub Jelinek
  2019-07-09 20:06           ` Gerald Pfeifer
  0 siblings, 1 reply; 11+ messages in thread
From: Jakub Jelinek @ 2019-01-19 22:52 UTC (permalink / raw)
  To: Gerald Pfeifer
  Cc: fortran, Thomas Koenig, gcc-patches, Mark Eggleston, Jeff Law

On Sat, Jan 19, 2019 at 11:49:34PM +0100, Gerald Pfeifer wrote:
> Hej Jakub, hej Fortran hackers,
> 
> On Wed, 21 Nov 2018, Jakub Jelinek wrote:
> > Like this?  Ok for trunk/wwwdocs?
> > 
> > 2018-11-21  Jakub Jelinek  <jakub@redhat.com>
> > 
> > 	* invoke.texi (-fdec-include): Document.
> 
> how about the refinement below?

LGTM.  Thanks.

> --- gcc-9/changes.html	11 Jan 2019 19:10:28 -0000	1.33
> +++ gcc-9/changes.html	19 Jan 2019 22:48:22 -0000
> @@ -170,12 +170,12 @@
>    module <code>IEEE_ARITHMETIC</code>.
>    </li>
>    <li>
> -    A new command line option <code>-fdec-include</code>, set also
> -    by <code>-fdec</code> option, has been added for an extension
> -    for compatibility with legacy code.  With this option,
> -    <code>INCLUDE</code> directive is parsed also as a statement,
> -    which allows the directive to be written on multiple source lines
> -    with line continuations.
> +    A new command-line option <code>-fdec-include</code>, set also
> +    by the <code>-fdec</code> option, has been added to increase
> +    compatibility with legacy code.  With this option, an
> +    <code>INCLUDE</code> directive is also parsed as a statement,
> +    which allows the directive to be spread across multiple source
> +    lines with line continuations.
>    </li>
>  </ul>
>  

	Jakub

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

* Re: Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support)
  2019-01-19 22:52         ` Jakub Jelinek
@ 2019-07-09 20:06           ` Gerald Pfeifer
  0 siblings, 0 replies; 11+ messages in thread
From: Gerald Pfeifer @ 2019-07-09 20:06 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: fortran, Thomas Koenig, gcc-patches, Mark Eggleston, Jeff Law

On Sat, 19 Jan 2019, Jakub Jelinek wrote:
>> how about the refinement below?
> LGTM.  Thanks.

The context has changed a bit since then (due to links being
added), so I had to manually re-apply the patch and committed
the following now.

Gerald

Index: changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/changes.html,v
retrieving revision 1.69
diff -u -r1.69 changes.html
--- changes.html	29 May 2019 22:22:01 -0000	1.69
+++ changes.html	9 Jul 2019 19:48:01 -0000
@@ -740,10 +740,10 @@
   </li>
   <li>
       A new command-line option <a href="https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gfortran/Fortran-Dialect-Options.html#index-fdec-include"><code>-fdec-include</code></a>, set also
-    by <a href="https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gfortran/Fortran-Dialect-Options.html#index-fdec"><code>-fdec</code></a> option, has been added for an extension
-    for compatibility with legacy code.  With this option,
-    <code>INCLUDE</code> directive is parsed also as a statement,
-    which allows the directive to be written on multiple source lines
+    by the <a href="https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gfortran/Fortran-Dialect-Options.html#index-fdec"><code>-fdec</code></a> option,
+    has been added to increase compatibility with legacy code.  With this
+    option, an <code>INCLUDE</code> directive is also parsed as a statement,
+    which allows the directive to be spread across multiple source lines
     with line continuations.
   </li>
   <li>

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

end of thread, other threads:[~2019-07-09 19:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-12 14:51 [PATCH] Fortran include line fixes and -fdec-include support Jakub Jelinek
2018-11-12 23:25 ` Fritz Reese
2018-11-13 10:06 ` Mark Eggleston
2018-11-13 10:53   ` Jakub Jelinek
2018-11-20 17:02 ` Patch ping (Re: [PATCH] Fortran include line fixes and -fdec-include support) Jakub Jelinek
2018-11-21  7:31   ` Thomas Koenig
2018-11-21  8:25     ` Jakub Jelinek
2018-11-21 19:31       ` Thomas Koenig
2019-01-19 22:49       ` Gerald Pfeifer
2019-01-19 22:52         ` Jakub Jelinek
2019-07-09 20:06           ` Gerald Pfeifer

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