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

_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 "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.
This commit is contained in:
Lewis Hyatt 2024-03-22 15:42:43 -04:00 committed by Lewis Hyatt
parent 998eb2a126
commit 8c56d697b3
No known key found for this signature in database
4 changed files with 17 additions and 3 deletions

View file

@ -0,0 +1 @@
#pragma GCC warning "this warning should not be output (1)"

View file

@ -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"

View file

@ -0,0 +1,3 @@
#include "pragma-system-header-2.h" /* { dg-bogus "this warning should not be output" } */
/* { dg-do preprocess } */
/* PR preprocessor/114436 */

View file

@ -2424,9 +2424,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);
@ -2491,6 +2493,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 ... */