https://gcc.gnu.org/g:9f0c207d4534a909ec04f9ffa306718154e67d70
commit r13-9214-g9f0c207d4534a909ec04f9ffa306718154e67d70 Author: Lewis Hyatt <lhy...@gmail.com> Date: Mon Oct 14 17:59:46 2024 -0400 libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118] The PR shows that we ICE after lexing an invalid unterminated raw string, because lex_raw_string() pops the main buffer unexpectedly. Resolve by handling this case the same way as for other directives. libcpp/ChangeLog: PR preprocessor/117118 * lex.cc (lex_raw_string): Treat an unterminated raw string the same way for a deferred pragma as is done for other directives. gcc/testsuite/ChangeLog: PR preprocessor/117118 * c-c++-common/raw-string-directive-3.c: New test. * c-c++-common/raw-string-directive-4.c: New test. Diff: --- gcc/testsuite/c-c++-common/raw-string-directive-3.c | 8 ++++++++ gcc/testsuite/c-c++-common/raw-string-directive-4.c | 8 ++++++++ libcpp/lex.cc | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-3.c b/gcc/testsuite/c-c++-common/raw-string-directive-3.c new file mode 100644 index 000000000000..fa4fa979fcef --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-3.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +#pragma message R"" diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-4.c b/gcc/testsuite/c-c++-common/raw-string-directive-4.c new file mode 100644 index 000000000000..935e3a1a9911 --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-4.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +_Pragma("message R\"\"") diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 8951ac56ee2d..d2d71761b231 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -2704,7 +2704,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) { pos--; pfile->buffer->cur = pos; - if ((pfile->state.in_directive || pfile->state.parsing_args) + if ((pfile->state.in_directive || pfile->state.parsing_args + || pfile->state.in_deferred_pragma) && pfile->buffer->next_line >= pfile->buffer->rlimit) { cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0,