diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-10-02 10:53:35 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-10-02 10:53:35 +0200 |
commit | 5943a2fa1bc5407332a91976c145446cdb8ded7b (patch) | |
tree | d86a1a80f6d73c57efd2da5d1b91d56f2075da84 /libcpp/internal.h | |
parent | ba53ccad554bb4f3c2b0e457a18557ae0f54b05e (diff) | |
download | gcc-5943a2fa1bc5407332a91976c145446cdb8ded7b.zip gcc-5943a2fa1bc5407332a91976c145446cdb8ded7b.tar.gz gcc-5943a2fa1bc5407332a91976c145446cdb8ded7b.tar.bz2 |
libcpp: Implement clang -Wheader-guard warning [PR96842]
The following patch implements the clang -Wheader-guard warning, which warns
if a valid multiple inclusion header guard's #ifndef/#if !defined directive
is immediately (no other non-line directives nor other (non-comment)
tokens in between) followed by #define directive for some different macro,
which in get_suggestion rules is close enough to the actual header guard
macro (i.e. likely misspelling), the #define is object-like with empty
definition (I've followed what clang implements) and the macro isn't defined
later on (at least not on the final #endif at the end of a header).
In this case it emits a warning, so that
#ifndef STDIO_H
#define STDOI_H
...
#endif
or similar misspellings can be caught.
clang enables this warning by default, but I've put it into -Wall instead
as it still seems to be a style warning, nothing more severe; if a header
doesn't survive multiple inclusion because of the misspelling, users will
get different diagnostics.
2024-10-02 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/96842
libcpp/
* include/cpplib.h (struct cpp_options): Add warn_header_guard member.
(enum cpp_warning_reason): Add CPP_W_HEADER_GUARD enumerator.
* internal.h (struct cpp_reader): Add mi_def_cmacro, mi_loc and
mi_def_loc members.
(_cpp_defined_macro_p): Constify type pointed by argument type.
Formatting fix.
* init.cc (cpp_create_reader): Clear
CPP_OPTION (pfile, warn_header_guard).
* directives.cc (struct if_stack): Add def_loc and mi_def_cmacro
members.
(DIRECTIVE_TABLE): Add IF_COND flag to define.
(do_define): Set ifs->mi_def_cmacro on a define immediately following
#ifndef directive for the guard. Clear pfile->mi_valid. Formatting
fix.
(do_endif): Copy over pfile->mi_def_cmacro and pfile->mi_def_loc
if ifs->mi_def_cmacro is set and pfile->mi_cmacro isn't a defined
macro.
(push_conditional): Clear mi_def_cmacro and mi_def_loc members.
* files.cc (_cpp_pop_file_buffer): Emit -Wheader-guard diagnostics.
gcc/
* doc/invoke.texi (Wheader-guard): Document.
gcc/c-family/
* c.opt (Wheader-guard): New option.
* c.opt.urls: Regenerated.
* c-ppoutput.cc (init_pp_output): Initialize also cb->get_suggestion.
gcc/testsuite/
* c-c++-common/cpp/Wheader-guard-1.c: New test.
* c-c++-common/cpp/Wheader-guard-1-1.h: New test.
* c-c++-common/cpp/Wheader-guard-1-2.h: New test.
* c-c++-common/cpp/Wheader-guard-1-3.h: New test.
* c-c++-common/cpp/Wheader-guard-1-4.h: New test.
* c-c++-common/cpp/Wheader-guard-1-5.h: New test.
* c-c++-common/cpp/Wheader-guard-1-6.h: New test.
* c-c++-common/cpp/Wheader-guard-1-7.h: New test.
* c-c++-common/cpp/Wheader-guard-1-8.h: New test.
* c-c++-common/cpp/Wheader-guard-1-9.h: New test.
* c-c++-common/cpp/Wheader-guard-1-10.h: New test.
* c-c++-common/cpp/Wheader-guard-1-11.h: New test.
* c-c++-common/cpp/Wheader-guard-1-12.h: New test.
* c-c++-common/cpp/Wheader-guard-2.c: New test.
* c-c++-common/cpp/Wheader-guard-2.h: New test.
* c-c++-common/cpp/Wheader-guard-3.c: New test.
* c-c++-common/cpp/Wheader-guard-3.h: New test.
Diffstat (limited to 'libcpp/internal.h')
-rw-r--r-- | libcpp/internal.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/libcpp/internal.h b/libcpp/internal.h index fa64a69..b69a037 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -495,9 +495,11 @@ struct cpp_reader been used. */ bool seen_once_only; - /* Multiple include optimization. */ + /* Multiple include optimization and -Wheader-guard warning. */ const cpp_hashnode *mi_cmacro; const cpp_hashnode *mi_ind_cmacro; + const cpp_hashnode *mi_def_cmacro; + location_t mi_loc, mi_def_loc; bool mi_valid; /* Lexing. */ @@ -696,7 +698,8 @@ _cpp_in_main_source_file (cpp_reader *pfile) } /* True if NODE is a macro for the purposes of ifdef, defined etc. */ -inline bool _cpp_defined_macro_p (cpp_hashnode *node) +inline bool +_cpp_defined_macro_p (const cpp_hashnode *node) { /* Do not treat conditional macros as being defined. This is due to the powerpc port using conditional macros for 'vector', 'bool', |