From 056f95ec951178a110b57e58a2ee434907de2e38 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 5 Sep 2019 11:23:48 +0000 Subject: [PATCH] [preprocessor/91639] #includes at EOF https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00280.html libcpp/ PR preprocessor/91639 * directives.c (do_include_common): Tell lexer we're a #include. * files.c (_cpp_stack_file): Lexer will have always incremented. * internal.h (struct cpp_context): Extend in_directive's semantics. * lex.c (_cpp_lex_direct): Increment line for final \n when lexing for an ISO #include. * line-map.c (linemap_line_start): Remember if we overflowed. gcc/testsuite/ PR preprocessor/91639 * c-c++-common/cpp/pr91639.c: New. * c-c++-common/cpp/pr91639-one.h: New. * c-c++-common/cpp/pr91639-two.h: New. From-SVN: r275402 --- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/c-c++-common/cpp/pr91639-one.h | 2 ++ gcc/testsuite/c-c++-common/cpp/pr91639-two.h | 1 + gcc/testsuite/c-c++-common/cpp/pr91639.c | 9 ++++++ libcpp/ChangeLog | 11 ++++++++ libcpp/directives.c | 4 +++ libcpp/files.c | 29 +++++++------------- libcpp/internal.h | 3 +- libcpp/lex.c | 8 +++++- libcpp/line-map.c | 6 +++- 10 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639-one.h create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639-two.h create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ce3a385d3ed..cdaa2705287 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Nathan Sidwell + + PR preprocessor/91639 + * c-c++-common/cpp/pr91639.c: New. + * c-c++-common/cpp/pr91639-one.h: New. + * c-c++-common/cpp/pr91639-two.h: New. + 2019-09-05 Richard Sandiford PR middle-end/91577 diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639-one.h b/gcc/testsuite/c-c++-common/cpp/pr91639-one.h new file mode 100644 index 00000000000..141f6a732f7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639-one.h @@ -0,0 +1,2 @@ +one +#include "pr91639-two.h" diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639-two.h b/gcc/testsuite/c-c++-common/cpp/pr91639-two.h new file mode 100644 index 00000000000..f719efd430d --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639-two.h @@ -0,0 +1 @@ +two diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639.c b/gcc/testsuite/c-c++-common/cpp/pr91639.c new file mode 100644 index 00000000000..6da0b669ddc --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639.c @@ -0,0 +1,9 @@ +/* PR91639 Line markers for an end-of-file #include */ +/* { dg-do preprocess } */ +/* { dg-additional-options -Wno-pedantic } */ +/* { dg-additional-files {pr91639-one.h pr91639-two.h} } */ + +#include "pr91639-one.h" +main + +/* { dg-final { scan-file pr91639.i "# 1 \"\[^\n\"\]*pr91639-one.h\" 1\none\n# 1 \"\[^\n\"\]*pr91639-two.h\" 1\ntwo\n# 3 \"\[^\n\"\]*pr91639-one.h\" 2\n# 7 \"\[^\n\"\]*pr91639.c\" 2\nmain\n" } } */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 6791b3644e5..c418d75c950 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,14 @@ +2019-09-05 Nathan Sidwell + + PR preprocessor/91639 + * directives.c (do_include_common): Tell lexer we're a #include. + * files.c (_cpp_stack_file): Lexer will have always incremented. + * internal.h (struct cpp_context): Extend in_directive's + semantics. + * lex.c (_cpp_lex_direct): Increment line for final \n when lexing + for an ISO #include. + * line-map.c (linemap_line_start): Remember if we overflowed. + 2019-09-03 Ulrich Weigand * directives.c: Remove references to spu from comments. diff --git a/libcpp/directives.c b/libcpp/directives.c index 29d21ed9fdf..1c6b31e143b 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -818,6 +818,10 @@ do_include_common (cpp_reader *pfile, enum include_type type) callback can dump comments which follow #include. */ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + /* Tell the lexer this is an include directive -- we want it to + increment the line number even if this is the last line of a file. */ + pfile->state.in_directive = 2; + fname = parse_include (pfile, &angle_brackets, &buf, &location); if (!fname) goto done; diff --git a/libcpp/files.c b/libcpp/files.c index ee31aff606d..aa77dc74e94 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -938,25 +938,16 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type, pfile->mi_valid = true; pfile->mi_cmacro = 0; - /* Compensate for the increment in linemap_add that occurs when in - do_file_change. In the case of a normal #include, we're - currently at the start of the line *following* the #include. A - separate location_t for this location makes no sense (until we do - the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION. This - does not apply if we found a PCH file (in which case linemap_add - is not called) or we were included from the command-line. In the - case that the #include is the last line in the file, - highest_location still points to the current line, not the start - of the next line, so we do not decrement in this case. See - plugin/location-overflow-test-pr83173.h for an example. */ - bool decremented = false; - if (file->pchname == NULL && file->err_no == 0 && type < IT_DIRECTIVE_HWM) - { - decremented = (pfile->line_table->highest_line - == pfile->line_table->highest_location); - if (decremented) - pfile->line_table->highest_location--; - } + /* In the case of a normal #include, we're now at the start of the + line *following* the #include. A separate location_t for this + location makes no sense, until we do the LC_LEAVE. + + This does not apply if we found a PCH file, we're not a regular + include, or we ran out of locations. */ + if (file->pchname == NULL + && type < IT_DIRECTIVE_HWM + && pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1) + pfile->line_table->highest_location--; /* Add line map and do callbacks. */ _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp); diff --git a/libcpp/internal.h b/libcpp/internal.h index d4768aee713..f9bcd37c571 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -234,7 +234,8 @@ struct cpp_context struct lexer_state { - /* Nonzero if first token on line is CPP_HASH. */ + /* 1 if we're handling a directive. 2 if it's an include-like + directive. */ unsigned char in_directive; /* Nonzero if in a directive that will handle padding tokens itself. diff --git a/libcpp/lex.c b/libcpp/lex.c index 16ded6e9b05..52e5bceb3ff 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -2771,7 +2771,13 @@ _cpp_lex_direct (cpp_reader *pfile) goto skipped_white; case '\n': - if (buffer->cur < buffer->rlimit) + /* Increment the line, unless this is the last line ... */ + if (buffer->cur < buffer->rlimit + /* ... or this is a #include, (where _cpp_stack_file needs to + unwind by one line) ... */ + || (pfile->state.in_directive > 1 + /* ... except traditional-cpp increments this elsewhere. */ + && !CPP_OPTION (pfile, traditional))) CPP_INCREMENT_LINE (pfile, 0); buffer->need_line = true; goto fresh_line; diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 572d7f416f5..d6924eb3e78 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -764,7 +764,11 @@ linemap_line_start (line_maps *set, linenum_type to_line, /* Locations of ordinary tokens are always lower than locations of macro tokens. */ if (r >= LINE_MAP_MAX_LOCATION) - return 0; + { + /* Remember we overflowed. */ + set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1; + return 0; + } set->highest_line = r; if (r > set->highest_location) -- 2.30.2