diff mbox series

libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118]

Message ID 20241016154437.3244765-1-lhyatt@gmail.com
State New
Headers show
Series libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118] | expand

Commit Message

Lewis Hyatt Oct. 16, 2024, 3:44 p.m. UTC
Hello-

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117118

This fixes an old regression from GCC 11. Is it OK for trunk and all
backports please? Bootstrap + regtested all languages on x86-64 Linux.
Thanks!

-Lewis

-- >8 --

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.
---
 libcpp/lex.cc                                       | 3 ++-
 gcc/testsuite/c-c++-common/raw-string-directive-3.c | 8 ++++++++
 gcc/testsuite/c-c++-common/raw-string-directive-4.c | 8 ++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/c-c++-common/raw-string-directive-3.c
 create mode 100644 gcc/testsuite/c-c++-common/raw-string-directive-4.c
diff mbox series

Patch

diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index bb5cd394ab4..f9c5a070410 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -2655,7 +2655,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,
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 00000000000..fa4fa979fce
--- /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 00000000000..935e3a1a991
--- /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\"\"")