https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120778

--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:64859dc6e2948616439b500b5d9ffb2635b45ae8

commit r16-3059-g64859dc6e2948616439b500b5d9ffb2635b45ae8
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Aug 7 08:47:44 2025 +0200

    c++, c: Introduce -Wkeyword-macro warning/pedwarn - part of C++26 P2843R3
[PR120778]

    The following patch introduces a -Wkeyword-macro warning that clang has
    since 2014 to implement part of C++26 P2843R3 Preprocessing is never
undefined
    paper.
    The relevant change in the paper is moving [macro.names]/2 paragraph to
    https://eel.is/c++draft/cpp.replace.general#9 :
    "A translation unit shall not #define or #undef names lexically identical
to
    keywords, to the identifiers listed in Table 4, or to the attribute-tokens
    described in [dcl.attr], except that the names likely and unlikely may be
    defined as function-like macros."

    Now, my understanding of the paper is that in [macro.names] and surrounding
    sections the word shall bears different meaning from [cpp.replace.general],
    where only the latter location implies ill-formed, diagnostic required.

    The warning in clang when introduced diagnosed all #define/#undef
directives
    on keywords, but shortly after introduction has been changed not to
    diagnose #undef at all (with "#undef a keyword is generally harmless but
used
    often in configuration scripts" message) and later on even the #define
    part tweaked - not warn about say
      #define inline
    (or const, extern, static), or
      #define keyword keyword
    or
      #define keyword __keyword
    or
      #define keyword __keyword__
    Later on the warning has been moved to be only pedantic diagnostic unless
    requested by users.  Clearly some code in the wild does e.g.
      #define private public
    and similar games, or e.g. Linux kernel (sure, C) does
      #define inline __inline__ __attribute__((__always_inline__))
    etc.
    Now, I believe at least with the current C++26 wording such exceptions
    aren't allowed (unless it is changed to IFNDR).  But given that this is
just
    pedantic stuff, the following patch makes the warning off by default for
    C and C++ before C++26 and even for C++26 it enables it by default only
    if -pedantic/-pedantic-errors (in that case it pedwarns, otherwise it
    warns).  And it diagnoses both #define and #undef without exceptions.

    From what I can see, all the current NODE_WARN cases are macros starting
    with __ with one exception (_Pragma).  As the NODE_* flags seem to be a
    limited resource, I chose to just use NODE_WARN as well and differentiate
    on the node names (if they don't start with __ or _P, they are considered
    to be -Wkeyword-macro registered ones, otherwise old NODE_WARN cases,
    typically builtin macros or __STDC* macros).

    2025-08-07  Jakub Jelinek  <ja...@redhat.com>

            PR preprocessor/120778
    gcc/
            * doc/invoke.texi (Wkeyword-macro): Document.
    gcc/c-family/
            * c.opt (Wkeyword-macro): New option.
            * c.opt.urls: Regenerate.
            * c-common.h (cxx_dialect): Comment formatting fix.
            * c-opts.cc (c_common_post_options): Default to
            -Wkeyword-macro for C++26 if pedantic.
    gcc/c/
            * c-decl.cc (c_init_decl_processing): Mark cpp nodes corresponding
            to keywords as NODE_WARN if warn_keyword_macro.
    gcc/cp/
            * lex.cc (cxx_init): Mark cpp nodes corresponding
            to keywords, identifiers with special meaning and standard
            attribute identifiers as NODE_WARN if warn_keyword_macro.
    gcc/testsuite/
            * gcc.dg/Wkeyword-macro-1.c: New test.
            * gcc.dg/Wkeyword-macro-2.c: New test.
            * gcc.dg/Wkeyword-macro-3.c: New test.
            * gcc.dg/Wkeyword-macro-4.c: New test.
            * gcc.dg/Wkeyword-macro-5.c: New test.
            * gcc.dg/Wkeyword-macro-6.c: New test.
            * gcc.dg/Wkeyword-macro-7.c: New test.
            * gcc.dg/Wkeyword-macro-8.c: New test.
            * gcc.dg/Wkeyword-macro-9.c: New test.
            * g++.dg/warn/Wkeyword-macro-1.C: New test.
            * g++.dg/warn/Wkeyword-macro-2.C: New test.
            * g++.dg/warn/Wkeyword-macro-3.C: New test.
            * g++.dg/warn/Wkeyword-macro-4.C: New test.
            * g++.dg/warn/Wkeyword-macro-5.C: New test.
            * g++.dg/warn/Wkeyword-macro-6.C: New test.
            * g++.dg/warn/Wkeyword-macro-7.C: New test.
            * g++.dg/warn/Wkeyword-macro-8.C: New test.
            * g++.dg/warn/Wkeyword-macro-9.C: New test.
            * g++.dg/warn/Wkeyword-macro-10.C: New test.
            * g++.dg/opt/pr82577.C: Don't #define register to nothing for
            C++17 and later.  Instead define reg macro to nothing for C++17
            and later or to register and use it instead of register.
            * g++.dg/modules/atom-preamble-3.C: Add -Wno-keyword-macro to
            dg-additional-options.
            * g++.dg/template/sfinae17.C (static_assert): Rename macro to ...
            (my_static_assert): ... this.
            (main): Use my_static_assert instead of static_assert.
    libcpp/
            * include/cpplib.h (struct cpp_options): Add
cpp_warn_keyword_macro.
            (enum cpp_warning_reason): Add CPP_W_KEYWORD_MACRO enumerator.
            (cpp_keyword_p): New inline function.
            * directives.cc (do_undef): Support -Wkeyword-macro diagnostics.
            * macro.cc (warn_of_redefinition): Ignore NODE_WARN flag on nodes
            registered for -Wkeyword-macro.
            (_cpp_create_definition): Support -Wkeyword-macro diagnostics.
            Formatting fixes.

Reply via email to