aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-05-12 15:14:35 +0200
committerJakub Jelinek <jakub@redhat.com>2021-05-12 15:14:35 +0200
commitc6b664e2c4c127025e076d8b584abe0976694629 (patch)
treeb83d6b28af9baa0cbd624ac68d008f507f663db2
parentfc186594e3ee86a57841442e96306dddfd8eb85d (diff)
downloadgcc-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.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr100392.h4
-rw-r--r--libcpp/lex.c13
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);
}