On Wed, 2024-09-11 at 23:26 +0200, Jakub Jelinek wrote:
> Hi!
> 
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 

Overall, LGTM, but I'm not as familiar with libcpp's implementation
details.

> 
> --- libcpp/files.cc.jj        2024-09-03 16:47:47.322031849 +0200
> +++ libcpp/files.cc   2024-09-11 19:32:43.754868132 +0200
> @@ -1664,7 +1664,28 @@ _cpp_pop_file_buffer (cpp_reader *pfile,
>    /* Record the inclusion-preventing macro, which could be NULL
>       meaning no controlling macro.  */
>    if (pfile->mi_valid && file->cmacro == NULL)
> -    file->cmacro = pfile->mi_cmacro;
> +    {
> +      file->cmacro = pfile->mi_cmacro;
> +      if (pfile->mi_cmacro
> +       && pfile->mi_def_cmacro
> +       && pfile->cb.get_suggestion)
> +     {
> +       const char *names[]
> +         = { (const char *) NODE_NAME (pfile->mi_def_cmacro),
> NULL };
> +       if (pfile->cb.get_suggestion (pfile,
> +                                     (const char *)
> +                                     NODE_NAME (pfile-
> >mi_cmacro), names)
> +           && cpp_warning_with_line (pfile, CPP_W_HEADER_GUARD,
> +                                     pfile->mi_loc, 0,
> +                                     "header guard \"%s\"
> followed by "
> +                                     "\"#define\" of a different
> macro",
> +                                     NODE_NAME (pfile-
> >mi_cmacro)))
> +         cpp_error_at (pfile, CPP_DL_NOTE, pfile->mi_def_loc,
> +                       "\"%s\" is defined here; did you mean
> \"%s\"?",
> +                       NODE_NAME (pfile->mi_def_cmacro),
> +                       NODE_NAME (pfile->mi_cmacro));
> +     }

We were chatting on IRC about how it would be nice to be able to use
%qs in libcppp diagnostics; here is an example (rather than using
\"%s\").

Not a blocker, but it occurs to me that ideally we'd group the warning
and note into a diagnostic group, but unfortunately there's no way to
express that currently via the interface libcpp has.  We would need to
add {begin,end}_group hooks, which in turn suggests that maybe that
libcpp's interface into diagnostics should be an abstract base class
with various vfuncs, rather than a callback.

Also not a blocker, but it would nice to have a fix-it hint here, by
using the rich_location overload of cpp_error_at and adding a fix-it
hint to the rich_location.

Hope this is constructive
Dave

Reply via email to