Blame SOURCES/gcc8-fortran-include.patch

2985e0
commit 858a1903ea946c9947d492209453a8973846b9f7
2985e0
Author: Jeff Law <law@torsion.usersys.redhat.com>
2985e0
Date:   Tue May 29 13:56:59 2018 -0400
2985e0
2985e0
    Fix bloomberg INCLUDE issue
2985e0
2985e0
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
2985e0
index 55d6daf..9c9a208 100644
2985e0
--- a/gcc/fortran/scanner.c
2985e0
+++ b/gcc/fortran/scanner.c
2985e0
@@ -2129,6 +2129,38 @@ preprocessor_line (gfc_char_t *c)
2985e0
   current_file->line++;
2985e0
 }
2985e0
 
2985e0
+/* Add LINE with length LEN and truncation status TRUNC to
2985e0
+   FILE_CHANGES.  */
2985e0
+static void
2985e0
+add_line (gfc_char_t *line, int len, int trunc)
2985e0
+{
2985e0
+  gfc_linebuf *b;
2985e0
+
2985e0
+  b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
2985e0
+		+ (len + 1) * sizeof (gfc_char_t));
2985e0
+
2985e0
+
2985e0
+  b->location = linemap_line_start (line_table, current_file->line++, len);
2985e0
+  /* ??? We add the location for the maximum column possible here,
2985e0
+     because otherwise if the next call creates a new line-map, it
2985e0
+     will not reserve space for any offset.  */
2985e0
+  if (len > 0)
2985e0
+    linemap_position_for_column (line_table, len);
2985e0
+
2985e0
+  b->file = current_file;
2985e0
+  b->truncated = trunc;
2985e0
+  wide_strcpy (b->line, line);
2985e0
+
2985e0
+  if (line_head == NULL)
2985e0
+    line_head = b;
2985e0
+  else
2985e0
+    line_tail->next = b;
2985e0
+
2985e0
+  line_tail = b;
2985e0
+
2985e0
+  while (file_changes_cur < file_changes_count)
2985e0
+    file_changes[file_changes_cur++].lb = b;
2985e0
+}
2985e0
 
2985e0
 static bool load_file (const char *, const char *, bool);
2985e0
 
2985e0
@@ -2139,7 +2171,7 @@ static bool load_file (const char *, const char *, bool);
2985e0
    processed or true if we matched an include.  */
2985e0
 
2985e0
 static bool
2985e0
-include_line (gfc_char_t *line)
2985e0
+include_line (FILE *input, gfc_char_t *line, int *len, int *trunc)
2985e0
 {
2985e0
   gfc_char_t quote, *c, *begin, *stop;
2985e0
   char *filename;
2985e0
@@ -2173,6 +2205,33 @@ include_line (gfc_char_t *line)
2985e0
   while (*c == ' ' || *c == '\t')
2985e0
     c++;
2985e0
 
2985e0
+  /* If we have reached EOL, read ahead to find the quote.  We eat
2985e0
+     any whitespace.  We use getchar behind the back of load_line and
2985e0
+     put it back if we do not find what we are looking for.  */
2985e0
+  int new_line_len = 0;
2985e0
+  int new_trunc = 0;
2985e0
+  gfc_char_t *new_line = NULL;
2985e0
+  if (*c == '\0')
2985e0
+    {
2985e0
+      unsigned char x;
2985e0
+
2985e0
+      do
2985e0
+	x = getc (input);
2985e0
+      while (x == ' ' || x == '\t' || x == '\r' || x == '\n');
2985e0
+
2985e0
+      /* Always put the character back.  */
2985e0
+      ungetc (x, input);
2985e0
+
2985e0
+      /* If we did not fine the quote, put the character back and
2985e0
+	 return that no INCLUDE has processed.  */
2985e0
+      if (x != '"' && x != '\'')
2985e0
+	return false;
2985e0
+
2985e0
+      /* Read the next line and continue processing.  */
2985e0
+      new_trunc = load_line (input, &new_line, &new_line_len, NULL);
2985e0
+      c = new_line;
2985e0
+    }
2985e0
+
2985e0
   /* Find filename between quotes.  */
2985e0
   
2985e0
   quote = *c++;
2985e0
@@ -2184,16 +2243,45 @@ include_line (gfc_char_t *line)
2985e0
   while (*c != quote && *c != '\0')
2985e0
     c++;
2985e0
 
2985e0
+  /* Reached EOL without finding ending quote.  */
2985e0
   if (*c == '\0')
2985e0
-    return false;
2985e0
+    {
2985e0
+      /* If we loaded another line, then we want to add the
2985e0
+	 original line and return the current line.
2985e0
+
2985e0
+	 We do not try to support multi-line filenames for
2985e0
+	 INCLUDE statements.  */
2985e0
+      if (new_line)
2985e0
+	{
2985e0
+	  add_line (line, *len, *trunc);
2985e0
+	  *line = *new_line;
2985e0
+	  *len = new_line_len;
2985e0
+	  *trunc = new_trunc;
2985e0
+	}
2985e0
+      return false;
2985e0
+    }
2985e0
 
2985e0
   stop = c++;
2985e0
   
2985e0
+  /* Consume trailing whitespace on this line.  */
2985e0
   while (*c == ' ' || *c == '\t')
2985e0
     c++;
2985e0
 
2985e0
+  /* If we encounter real characters before reaching EOL, then
2985e0
+     we do not consider this an include line.  */
2985e0
   if (*c != '\0' && *c != '!')
2985e0
-    return false;
2985e0
+    {
2985e0
+      /* If we loaded another line, then we want to add the
2985e0
+	 original line and return the current line.  */
2985e0
+      if (new_line)
2985e0
+	{
2985e0
+	  add_line (line, *len, *trunc);
2985e0
+	  *line = *new_line;
2985e0
+	  *len = new_line_len;
2985e0
+	  *trunc = new_trunc;
2985e0
+	}
2985e0
+      return false;
2985e0
+    }
2985e0
 
2985e0
   /* We have an include line at this point.  */
2985e0
 
2985e0
@@ -2215,7 +2303,6 @@ static bool
2985e0
 load_file (const char *realfilename, const char *displayedname, bool initial)
2985e0
 {
2985e0
   gfc_char_t *line;
2985e0
-  gfc_linebuf *b;
2985e0
   gfc_file *f;
2985e0
   FILE *input;
2985e0
   int len, line_len;
2985e0
@@ -2370,39 +2457,13 @@ load_file (const char *realfilename, const char *displayedname, bool initial)
2985e0
 	 but the first line that's not a preprocessor line.  */
2985e0
       first_line = false;
2985e0
 
2985e0
-      if (include_line (line))
2985e0
+      if (include_line (input, line, &len, &trunc))
2985e0
 	{
2985e0
 	  current_file->line++;
2985e0
 	  continue;
2985e0
 	}
2985e0
 
2985e0
-      /* Add line.  */
2985e0
-
2985e0
-      b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
2985e0
-		    + (len + 1) * sizeof (gfc_char_t));
2985e0
-
2985e0
-
2985e0
-      b->location
2985e0
-	= linemap_line_start (line_table, current_file->line++, len);
2985e0
-      /* ??? We add the location for the maximum column possible here,
2985e0
-	 because otherwise if the next call creates a new line-map, it
2985e0
-	 will not reserve space for any offset.  */
2985e0
-      if (len > 0)
2985e0
-	linemap_position_for_column (line_table, len);
2985e0
-
2985e0
-      b->file = current_file;
2985e0
-      b->truncated = trunc;
2985e0
-      wide_strcpy (b->line, line);
2985e0
-
2985e0
-      if (line_head == NULL)
2985e0
-	line_head = b;
2985e0
-      else
2985e0
-	line_tail->next = b;
2985e0
-
2985e0
-      line_tail = b;
2985e0
-
2985e0
-      while (file_changes_cur < file_changes_count)
2985e0
-	file_changes[file_changes_cur++].lb = b;
2985e0
+      add_line (line, len, trunc);
2985e0
     }
2985e0
 
2985e0
   /* Release the line buffer allocated in load_line.  */
2985e0
diff --git a/gcc/testsuite/gfortran.dg/include_10.f90 b/gcc/testsuite/gfortran.dg/include_10.f90
2985e0
new file mode 100644
2985e0
index 0000000..5a9bb5b
2985e0
--- /dev/null
2985e0
+++ b/gcc/testsuite/gfortran.dg/include_10.f90
2985e0
@@ -0,0 +1,11 @@
2985e0
+! { dg-do compile }
2985e0
+!
2985e0
+! Ensure that we handle the pathname on a separate line than
2985e0
+! the include directivbe
2985e0
+!
2985e0
+
2985e0
+subroutine one()
2985e0
+  include
2985e0
+   "include_4.inc"
2985e0
+  integer(i4) :: i
2985e0
+end subroutine one
2985e0
diff --git a/gcc/testsuite/gfortran.dg/include_11.f90 b/gcc/testsuite/gfortran.dg/include_11.f90
2985e0
new file mode 100644
2985e0
index 0000000..44b23e03
2985e0
--- /dev/null
2985e0
+++ b/gcc/testsuite/gfortran.dg/include_11.f90
2985e0
@@ -0,0 +1,10 @@
2985e0
+! { dg-do compile }
2985e0
+!
2985e0
+! Ensure that we can make an assignment to a variable named
2985e0
+! include.
2985e0
+!
2985e0
+
2985e0
+subroutine one()
2985e0
+  integer :: include
2985e0
+  include = 5
2985e0
+end subroutine one
2985e0
diff --git a/gcc/testsuite/gfortran.dg/include_12.f90 b/gcc/testsuite/gfortran.dg/include_12.f90
2985e0
new file mode 100644
2985e0
index 0000000..8679b20
2985e0
--- /dev/null
2985e0
+++ b/gcc/testsuite/gfortran.dg/include_12.f90
2985e0
@@ -0,0 +1,11 @@
2985e0
+! { dg-do compile }
2985e0
+!
2985e0
+! Ensure we can make an assignment to a variable named include using
2985e0
+! a line continuation
2985e0
+!
2985e0
+
2985e0
+subroutine one()
2985e0
+  integer :: include
2985e0
+  include &
2985e0
+     = 5
2985e0
+end subroutine one