2017-10-01  Rasmus Villemoes  <r...@rasmusvillemoes.dk>

        PR preprocessor/64965
        * gcc.c-torture/compile/pr64965.c: New test.

If the current filename contains a newline character, __FILE__ would
expand to a string literal containing an actual embedded newline,
which is of course illegal. Similarly, even in the absence of __FILE__
in the source file, gcc -E produces broken #line directives, making
the preprocessed output unsuitable for subsequent processing (though
compiling directly does work). Fix it by also escaping newline
characters.

[I'm not sure supporting newlines in file names actually makes the
world a better place.]

Signed-off-by: Rasmus Villemoes <r...@rasmusvillemoes.dk>
---
 gcc/testsuite/gcc.c-torture/compile/pr64695.c |  2 ++
 libcpp/macro.c                                | 10 ++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr64695.c

diff --git gcc/testsuite/gcc.c-torture/compile/pr64695.c 
gcc/testsuite/gcc.c-torture/compile/pr64695.c
new file mode 100644
index 00000000000..f31a031377c
--- /dev/null
+++ gcc/testsuite/gcc.c-torture/compile/pr64695.c
@@ -0,0 +1,2 @@
+#line 1 "new\nline"
+const char f[] = __FILE__;
diff --git libcpp/macro.c libcpp/macro.c
index 147fcf53a88..ef0d766cc00 100644
--- libcpp/macro.c
+++ libcpp/macro.c
@@ -493,8 +493,9 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node,
 }
 
 /* Copies SRC, of length LEN, to DEST, adding backslashes before all
-   backslashes and double quotes. DEST must be of sufficient size.
-   Returns a pointer to the end of the string.  */
+   backslashes and double quotes, and replacing newline characters
+   with \n.  DEST must be of sufficient size.  Returns a pointer to
+   the end of the string.  */
 uchar *
 cpp_quote_string (uchar *dest, const uchar *src, unsigned int len)
 {
@@ -507,6 +508,11 @@ cpp_quote_string (uchar *dest, const uchar *src, unsigned 
int len)
          *dest++ = '\\';
          *dest++ = c;
        }
+      else if (c == '\n')
+       {
+         *dest++ = '\\';
+         *dest++ = 'n';
+       }
       else
          *dest++ = c;
     }
-- 
2.11.0

Reply via email to