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,

Reply via email to