Bug 53920 - "gcc -E" does not honor #pragma GCC diagnostic ignored "-Wunused-macro"
Summary: "gcc -E" does not honor #pragma GCC diagnostic ignored "-Wunused-macro"
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, easyhack
: 64698 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-07-10 17:50 UTC by Samuel Bronson
Modified: 2022-12-29 21:39 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-11-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Bronson 2012-07-10 17:50:08 UTC
iMac:gcc-bugs user$ cat cpp-pragma-GCC-diagnostic.c

#pragma GCC diagnostic ignored "-Wunused-macros"
#define FOO

iMac:gcc-bugs user$ gcc-fsf-4.7 -Wunused-macros cpp-pragma-GCC-diagnostic.c -E
# 1 "cpp-pragma-GCC-diagnostic.c"
# 1 "<command-line>"
# 1 "cpp-pragma-GCC-diagnostic.c"

#pragma GCC diagnostic ignored "-Wunused-macros"
cpp-pragma-GCC-diagnostic.c:3:0: warning: macro "FOO" is not used [-Wunused-macros]
iMac:gcc-bugs user$ gcc-fsf-4.7 --version
gcc-fsf-4.7 (GCC) 4.7.1
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Comment 1 Samuel Bronson 2012-07-10 19:07:26 UTC
Oh, I suppose I should mention that I ran into this because I was using ccache to compile Emacs with --enable-gcc-warnings, and by default ccache runs the preprocessor and the compiler in separate passes (so that it can skip the compilation proper if it has cached output for a given preprocessor output), and then pastes together the diagnostic output from the two passes.

(Thankfully, setting the environment variable CCACHE_CPP2 causes ccache to throw out the preprocessor output after hashing, which is a quite effective workaround for this sort of thing, though preprocessing the source twice does make things a bit slower on cache misses.)
Comment 2 Manuel López-Ibáñez 2013-11-16 20:41:39 UTC
The C FE normally preprocesses and parses concurrently. But -E (only preprocessing) is handled by a different function in c-ppoutput.c(scan_translation_unit), which does not handle pragma diagnostics. So someone would need to add that handling there. Probably not difficult. I think one just needs to call c_invoke_pragma handler when a pragma diagnostic is detected, but someone has to try and flush out the details. If you need help just ask.
Comment 3 Markus F.X.J. Oberhumer 2021-05-27 13:15:18 UTC
Still a problem in 2021 with gcc-11.1.0
Comment 4 Lewis Hyatt 2022-06-17 18:57:08 UTC
*** Bug 64698 has been marked as a duplicate of this bug. ***
Comment 5 Lewis Hyatt 2022-06-17 18:59:46 UTC
I have a patch awaiting review to fix PR53431 which would fix this one too.
https://gcc.gnu.org/pipermail/gcc-patches/2022-May/595556.html
Comment 6 GCC Commits 2022-07-06 19:40:12 UTC
The master branch has been updated by Lewis Hyatt <lhyatt@gcc.gnu.org>:

https://gcc.gnu.org/g:e46f4d7430c5210465791603735ab219ef263c51

commit r13-1544-ge46f4d7430c5210465791603735ab219ef263c51
Author: Lewis Hyatt <lhyatt@gmail.com>
Date:   Tue Jul 5 17:15:28 2022 -0400

    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.
Comment 7 Lewis Hyatt 2022-07-06 19:44:33 UTC
Fixed for GCC 13.