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