diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-05-12 15:14:35 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-05-12 15:14:35 +0200 |
commit | c6b664e2c4c127025e076d8b584abe0976694629 (patch) | |
tree | b83d6b28af9baa0cbd624ac68d008f507f663db2 | |
parent | fc186594e3ee86a57841442e96306dddfd8eb85d (diff) | |
download | gcc-c6b664e2c4c127025e076d8b584abe0976694629.zip gcc-c6b664e2c4c127025e076d8b584abe0976694629.tar.gz gcc-c6b664e2c4c127025e076d8b584abe0976694629.tar.bz2 |
libcpp: Fix up -fdirectives-only preprocessing of includes not ending with newline [PR100392]
If a header doesn't end with a new-line, with -fdirectives-only we right now
preprocess it as
int i = 1;# 2 "pr100392.c" 2
i.e. the line directive isn't on the next line, which means we fail to parse
it when compiling.
GCC 10 and earlier libcpp/directives-only.c had for this:
if (!pfile->state.skipping && cur != base)
{
/* If the file was not newline terminated, add rlimit, which is
guaranteed to point to a newline, to the end of our range. */
if (cur[-1] != '\n')
{
cur++;
CPP_INCREMENT_LINE (pfile, 0);
lines++;
}
cb->print_lines (lines, base, cur - base);
}
and we have the assertion
/* Files always end in a newline or carriage return. We rely on this for
character peeking safety. */
gcc_assert (buffer->rlimit[0] == '\n' || buffer->rlimit[0] == '\r');
So, this patch just does readd the more less same thing, so that we emit
a newline after the inline even when it wasn't there before.
2021-05-12 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/100392
* lex.c (cpp_directive_only_process): If buffer doesn't end with '\n',
add buffer->rlimit[0] character to the printed range and
CPP_INCREMENT_LINE and increment line_count.
* gcc.dg/cpp/pr100392.c: New test.
* gcc.dg/cpp/pr100392.h: New file.
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/pr100392.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/pr100392.h | 4 | ||||
-rw-r--r-- | libcpp/lex.c | 13 |
3 files changed, 21 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.c b/gcc/testsuite/gcc.dg/cpp/pr100392.c new file mode 100644 index 0000000..670ad2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.c @@ -0,0 +1,5 @@ +/* PR preprocessor/100392 */ +/* { dg-do compile } */ +/* { dg-options "-save-temps -fdirectives-only" } */ + +#include "pr100392.h" diff --git a/gcc/testsuite/gcc.dg/cpp/pr100392.h b/gcc/testsuite/gcc.dg/cpp/pr100392.h new file mode 100644 index 0000000..340bc92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr100392.h @@ -0,0 +1,4 @@ +/* PR preprocessor/100392 */ + +/* No newline after ; below. */ +int i = 1;
\ No newline at end of file diff --git a/libcpp/lex.c b/libcpp/lex.c index 36cd2e3..6fd722a 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -4768,7 +4768,18 @@ cpp_directive_only_process (cpp_reader *pfile, } if (buffer->rlimit > base && !pfile->state.skipping) - cb (pfile, CPP_DO_print, data, line_count, base, buffer->rlimit - base); + { + const unsigned char *limit = buffer->rlimit; + /* If the file was not newline terminated, add rlimit, which is + guaranteed to point to a newline, to the end of our range. */ + if (limit[-1] != '\n') + { + limit++; + CPP_INCREMENT_LINE (pfile, 0); + line_count++; + } + cb (pfile, CPP_DO_print, data, line_count, base, limit - base); + } _cpp_pop_buffer (pfile); } |