Blame SOURCES/gcc7-fortran-include.patch

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