diff options
author | Lewis Hyatt <lhyatt@gmail.com> | 2022-07-05 17:15:28 -0400 |
---|---|---|
committer | Lewis Hyatt <lhyatt@gmail.com> | 2022-07-06 15:00:09 -0400 |
commit | e46f4d7430c5210465791603735ab219ef263c51 (patch) | |
tree | b30bcd37b4da28ccf92c9c5d93886467cf95e123 /gcc/c-family/c-common.h | |
parent | 208fbc779c713715da1465a1a2c6710c084c9b05 (diff) | |
download | gcc-e46f4d7430c5210465791603735ab219ef263c51.zip gcc-e46f4d7430c5210465791603735ab219ef263c51.tar.gz gcc-e46f4d7430c5210465791603735ab219ef263c51.tar.bz2 |
diagnostics: Honor #pragma GCC diagnostic in the preprocessor [PR53431]
As discussed on PR c++/53431, currently, "#pragma GCC diagnostic" does
not always take effect for diagnostics generated by libcpp. The reason
is that libcpp itself does not interpret this pragma and only sends it on
to the frontend, hence the pragma is only honored if the frontend
arranges for it. The C frontend does process the pragma immediately
(more or less) after seeing the token, so things work fine there. The PR
points out that it doesn't work for C++, because the C++ frontend
doesn't handle anything until it has read all the tokens from
libcpp. The underlying problem is not C++-specific, though, and for
instance, gcc -E has the same issue.
This commit fixes the PR by adding the concept of an early pragma handler that
can be registered by frontends, which gives them a chance to process
diagnostic pragmas from libcpp before it is too late for them to take
effect. The C++ and preprocess-only frontends are modified to use early
pragmas and correct the behavior.
gcc/c-family/ChangeLog:
PR preprocessor/53920
PR c++/53431
* c-common.cc (c_option_is_from_cpp_diagnostics): New function.
* c-common.h (c_option_is_from_cpp_diagnostics): Declare.
(c_pp_stream_token): Declare.
* c-ppoutput.cc (init_pp_output): Refactor logic about skipping
pragmas to...
(should_output_pragmas): ...here. New function.
(token_streamer::stream): Support handling early pragmas.
(do_line_change): Likewise.
(c_pp_stream_token): New function.
* c-pragma.cc (struct pragma_diagnostic_data): New helper class.
(pragma_diagnostic_lex_normal): New function. Moved logic for
interpreting GCC diagnostic pragmas here.
(pragma_diagnostic_lex_pp): New function for parsing diagnostic pragmas
directly from libcpp.
(handle_pragma_diagnostic): Refactor into helper function...
(handle_pragma_diagnostic_impl): ...here. New function.
(handle_pragma_diagnostic_early): New function.
(handle_pragma_diagnostic_early_pp): New function.
(struct pragma_ns_name): Renamed to...
(struct pragma_pp_data): ...this. Add new "early_handler" member.
(c_register_pragma_1): Support early pragmas in the preprocessor.
(c_register_pragma_with_early_handler): New function.
(c_register_pragma): Support the new early handlers in struct
internal_pragma_handler.
(c_register_pragma_with_data): Likewise.
(c_register_pragma_with_expansion): Likewise.
(c_register_pragma_with_expansion_and_data): Likewise.
(c_invoke_early_pragma_handler): New function.
(c_pp_invoke_early_pragma_handler): New function.
(init_pragma): Add early pragma support for diagnostic pragmas.
* c-pragma.h (struct internal_pragma_handler): Add new early handler
members.
(c_register_pragma_with_early_handler): Declare.
(c_invoke_early_pragma_handler): Declare.
(c_pp_invoke_early_pragma_handler): Declare.
gcc/cp/ChangeLog:
PR c++/53431
* parser.cc (cp_parser_pragma_kind): Move earlier in the file.
(cp_lexer_handle_early_pragma): New function.
(cp_lexer_new_main): Support parsing and handling early pragmas.
(c_parse_file): Adapt to changes in cp_lexer_new_main.
gcc/testsuite/ChangeLog:
PR preprocessor/53920
PR c++/53431
* c-c++-common/pragma-diag-11.c: New test.
* c-c++-common/pragma-diag-12.c: New test.
* c-c++-common/pragma-diag-13.c: New test.
Diffstat (limited to 'gcc/c-family/c-common.h')
-rw-r--r-- | gcc/c-family/c-common.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index a1e6a55..c090084 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -911,6 +911,7 @@ extern tree fold_for_warn (tree); extern tree c_common_get_narrower (tree, int *); extern bool get_attribute_operand (tree, unsigned HOST_WIDE_INT *); extern void c_common_finalize_early_debug (void); +extern bool c_option_is_from_cpp_diagnostics (int); /* Used by convert_and_check; in front ends. */ extern tree convert_init (tree, tree); @@ -1191,6 +1192,7 @@ extern void preprocess_file (cpp_reader *); extern void pp_file_change (const line_map_ordinary *); extern void pp_dir_change (cpp_reader *, const char *); extern bool check_missing_format_attribute (tree, tree); +extern void c_pp_stream_token (cpp_reader *, const cpp_token *, location_t loc); /* In c-omp.cc */ typedef wide_int_bitmask omp_clause_mask; |