commit 858a1903ea946c9947d492209453a8973846b9f7 Author: Jeff Law 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