Skip to content
Snippets Groups Projects
  • Jakub Jelinek's avatar
    5943a2fa
    libcpp: Implement clang -Wheader-guard warning [PR96842] · 5943a2fa
    Jakub Jelinek authored
    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.
    5943a2fa
    History
    libcpp: Implement clang -Wheader-guard warning [PR96842]
    Jakub Jelinek authored
    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.
init.cc 31.68 KiB