c++: directives-only preprocessing and include translation [PR 99050]
authorNathan Sidwell <nathan@acm.org>
Tue, 16 Feb 2021 20:23:12 +0000 (12:23 -0800)
committerNathan Sidwell <nathan@acm.org>
Tue, 16 Feb 2021 20:26:51 +0000 (12:26 -0800)
We make sure files end in \n by placing one at the limit of the buffer
(just past the end of what is read).  We need to do the same for
buffers generated via include-translation.  Fortunately they have
space.

libcpp/
* files.c (_cpp_stack_file): Make buffers end in unread \n.
gcc/testsuite/
* g++.dg/modules/pr99050_a.H: New.
* g++.dg/modules/pr99050_b.C: New.

gcc/testsuite/g++.dg/modules/pr99050_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/pr99050_b.C [new file with mode: 0644]
libcpp/files.c

diff --git a/gcc/testsuite/g++.dg/modules/pr99050_a.H b/gcc/testsuite/g++.dg/modules/pr99050_a.H
new file mode 100644 (file)
index 0000000..137e37f
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/99050 ICE with directives only
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+void f ();
diff --git a/gcc/testsuite/g++.dg/modules/pr99050_b.C b/gcc/testsuite/g++.dg/modules/pr99050_b.C
new file mode 100644 (file)
index 0000000..439e216
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-additional-options {-fdirectives-only -fmodules-ts} }
+#include "pr99050_a.H"
+
+int main () {}
+
+// { dg-final { scan-file pr99050_b.i {import  "[^\n]*99050_a.H" \[\[__translated\]\];\n} }  }
index 5ea3f8e1bf30f9f0cb8b64fc1e8a6009ff5c8b23..3a35f7c9743aa2fd0284a2444e40bf1a077da2f1 100644 (file)
@@ -918,13 +918,17 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
         because we don't usually need that location (we're popping an
         include file).  However in this case we do want to do the
         increment.  So push a writable buffer of two newlines to acheive
-        that.  */
-      static uchar newlines[] = "\n\n";
+        that.  (We also need an extra newline, so this looks like a regular
+        file, which we do that to to make sure we don't fall off the end in the
+        middle of a line.  */
+      static uchar newlines[] = "\n\n\n";
       cpp_push_buffer (pfile, newlines, 2, true);
 
+      size_t len = strlen (buf);
+      buf[len] = '\n'; /* See above  */
       cpp_buffer *buffer
        = cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf),
-                          strlen (buf), true);
+                          len, true);
       buffer->to_free = buffer->buf;
 
       file->header_unit = +1;