preprocessor: Reimplement raw string lexing [pr95149]
authorNathan Sidwell <nathan@acm.org>
Tue, 19 May 2020 18:28:05 +0000 (11:28 -0700)
committerNathan Sidwell <nathan@acm.org>
Tue, 19 May 2020 18:39:15 +0000 (11:39 -0700)
commited63c387aa0bc1846082524455a6ff1fcec40f9d
treec719e1e942b4b6c31305810786b212b933faae78
parent6e7ae154dc5ef8d92ba5405b71154dc2f46b8d1f
preprocessor: Reimplement raw string lexing [pr95149]

pr95149 is a false positive static analysis checker.  But it
encouranged me to fix raw string lexing, which does contain a
complicated macro and pointers to local variables.  The
reimplementation does away with that macro.  Part of the complication
is we need to undo some of the fresh line processing -- trigraph notes
and escaped line continuations.  But the undone characters need to go
through the raw string processing, as they can legitimately be part of
the prefix marker.  however, in this reformulation we only process one
line marker at a time[*], so there's a limited number of undone
characters.  We can arrange the buffering to make sure we don't split
such an append sequence, and then simply take the characters from the
append buffer.

The prefix scanner had a switch statement, which I discovered was not
optimized as well as an if of a bunch of explicit comparisons (pr
95208 filed).

Finally I adjusted the failure mode.  When we get a bad prefix, we lex
up until the next '"', thus often swallowing the whole raw string.
Previously we'd bail and then the lexer would usually generate stupid
tokens, particularly when meeting the ending '"'.

libcpp/
* lex.c (struct lit_accum): New.
(bufring_append): Replace by lit_accum::append.
(lex_raw_string): Reimplement, using fragments of the old version.
(lex_string): Adjust lex_raw_string call.

gcc/testsuite/
* c-c++-common/raw-string-14.c: Adjust errors.
* c-c++-common/raw-string-16.c: Likewise.
* c-c++-common/raw-string-5.c: Likewise.
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/raw-string-14.c
gcc/testsuite/c-c++-common/raw-string-16.c
gcc/testsuite/c-c++-common/raw-string-5.c
libcpp/ChangeLog
libcpp/lex.c