diff mbox series

libcpp: Fix _Pragma("GCC system_header") [PR114436]

Message ID 20240323213438.1754187-1-lhyatt@gmail.com
State New
Headers show
Series libcpp: Fix _Pragma("GCC system_header") [PR114436] | expand

Commit Message

Lewis Hyatt March 23, 2024, 9:34 p.m. UTC
Hello-

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

This is a small fix for the issue mentioned in the PR that _Pragma("GCC
system_header") does not work completely. I believe it was always the case
since _Pragma() support was first added. bootstrap + regtested all languages
on x86-64 Linux. Is it OK now or in stage 1 please? Thanks!

-Lewis

-- >8 --

_Pragma("GCC system_header") currently takes effect only partially. It does
succeed in updating the line_map, so that checks like in_system_header_at()
return correctly, but it does not update pfile->buffer->sysp.  One result is
that a subsequent #include does not set up the system header state properly
for the newly included file, as pointed out in the PR. Fix by propagating
the new system header state back to the buffer after processing the pragma.

libcpp/ChangeLog:

	PR preprocessor/114436
	* directives.cc (destringize_and_run): If the _Pragma changed the
	buffer system header state (e.g. because it was _Pragma("GCC
	system_header"), propagate that change back to the actual buffer too.

gcc/testsuite/ChangeLog:

	PR preprocessor/114436
	* c-c++-common/cpp/pragma-system-header-1.h: New test.
	* c-c++-common/cpp/pragma-system-header-2.h: New test.
	* c-c++-common/cpp/pragma-system-header.c: New test.
---
 libcpp/directives.cc                                  | 11 ++++++++---
 .../c-c++-common/cpp/pragma-system-header-1.h         |  1 +
 .../c-c++-common/cpp/pragma-system-header-2.h         |  5 +++++
 gcc/testsuite/c-c++-common/cpp/pragma-system-header.c |  3 +++
 4 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h
 create mode 100644 gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h
 create mode 100644 gcc/testsuite/c-c++-common/cpp/pragma-system-header.c
diff mbox series

Patch

diff --git a/libcpp/directives.cc b/libcpp/directives.cc
index 479f8c716e8..bbaf9db6af0 100644
--- a/libcpp/directives.cc
+++ b/libcpp/directives.cc
@@ -1919,9 +1919,11 @@  destringize_and_run (cpp_reader *pfile, const cpp_string *in,
      until we've read all of the tokens that we want.  */
   cpp_push_buffer (pfile, (const uchar *) result, dest - result,
 		   /* from_stage3 */ true);
-  /* ??? Antique Disgusting Hack.  What does this do?  */
-  if (pfile->buffer->prev)
-    pfile->buffer->file = pfile->buffer->prev->file;
+
+  /* This is needed for _Pragma("once") and _Pragma("GCC system_header") to work
+     properly.  */
+  pfile->buffer->file = pfile->buffer->prev->file;
+  pfile->buffer->sysp = pfile->buffer->prev->sysp;
 
   start_directive (pfile);
   _cpp_clean_line (pfile);
@@ -1986,6 +1988,9 @@  destringize_and_run (cpp_reader *pfile, const cpp_string *in,
 
   /* Finish inlining run_directive.  */
   pfile->buffer->file = NULL;
+  /* If the system header state changed due to #pragma GCC system_header, then
+     make that applicable to the real buffer too.  */
+  pfile->buffer->prev->sysp = pfile->buffer->sysp;
   _cpp_pop_buffer (pfile);
 
   /* Reset the old macro state before ...  */
diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h
new file mode 100644
index 00000000000..bd9ff0cb138
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h
@@ -0,0 +1 @@ 
+#pragma GCC warning "this warning should not be output (1)"
diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h
new file mode 100644
index 00000000000..a62d9e2685a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h
@@ -0,0 +1,5 @@ 
+_Pragma("GCC system_header")
+#include "pragma-system-header-1.h"
+#pragma GCC warning "this warning should not be output (2)"
+_Pragma("unknown")
+#include "pragma-system-header-1.h"
diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c b/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c
new file mode 100644
index 00000000000..fdea12009e1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c
@@ -0,0 +1,3 @@ 
+#include "pragma-system-header-2.h" /* { dg-bogus "this warning should not be output" } */
+/* { dg-do preprocess } */
+/* PR preprocessor/114436 */