Blob Blame History Raw
commit 858a1903ea946c9947d492209453a8973846b9f7
Author: Jeff Law <law@torsion.usersys.redhat.com>
Date:   Tue May 29 13:56:59 2018 -0400

    Fix bloomberg INCLUDE issue

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