On 7/14/26 1:52 PM, Jakub Jelinek wrote:
Hi!

Apparently in clang __clang__ is a predefined macro (predefined to 1).
Because of that, clang doesn't have alternate spelling of its scoped
attributes as
[[__clang__::__something__]]
but
[[_Clang::__something__]]
The former isn't accepted even with -U__clang__.
For GNU attributes they do handle
[[__gnu__::__something__]]
like GCC does (if they support a particular attribute).

So, I'm afraid if we want to stay compatible with this mess, we need
to do the same thing.

The following patch does that.
It emits a warning when one attempts to use the __clang__ attribute
namespace suggesting to use _Clang instead (clang++ does that too),
but in __has_cpp_attribute/__has_attribute doesn't do that, just ensures
that 0 is returned in that case (i.e. it is not canonicalized in that
case), just canonicalizes _Clang to clang.

Ok for trunk if this passes full bootstrap/regtest?

2026-07-14  Jakub Jelinek  <[email protected]>

        PR c++/120635
gcc/
        * doc/extend.texi: Document variant spelling of
        standard attributes and that alternate namespace
        spelling for clang namespace is _Clang rather
        than __clang__.  For no_specializations use
        _Clang:: rather than __clang__::.
gcc/c-family/
        * c-lex.cc (c_common_has_attribute): For __clang__
        namespace don't call canonicalize_attr_name and for
        _Clang use clang instead.
gcc/cp/
        * parser.cc (cp_parser_std_attribute): Add
        canonicalize_attr_ns_name lambda and use it instead of
        canonicalize_attr_name for namespaces.  Emit a warning
        on __clang__::.
        (cp_parser_std_attribute_spec): Emit a warning on
        using __clang__:.
gcc/testsuite/
        * g++.dg/cpp0x/attr-trivial_abi8.C: Add further tests.
        * g++.dg/cpp0x/attr-trivial_abi11.C: New test.
        * g++.dg/ext/attr-no_specializations1.C: Use _Clang:: instead of
        __clang__.
        * g++.dg/ext/attr-no_specializations2.C: Likewise.
        * g++.dg/ext/attr-no_specializations6.C: Likewise.
        * g++.dg/ext/attr-no_specializations7.C: Likewise.
        * g++.dg/ext/attr-no_specializations8.C: Likewise.
        * g++.dg/ext/attr-no_specializations10.C: Add further tests.
        * g++.dg/ext/attr-no_specializations12.C: New test.

--- gcc/doc/extend.texi.jj      2026-07-13 18:37:33.605239738 +0200
+++ gcc/doc/extend.texi 2026-07-14 19:08:44.872456333 +0200
@@ -1821,9 +1821,15 @@ entity is ignored with a warning.
Every GNU-specific attribute has an alternate name that is prefixed
  and suffixed by two underscores; for example, the alternate name of
-@code{weak} is @code{__weak__}.  These alternate names are useful in
-library header files in case they are included into files that have
+@code{weak} is @code{__weak__}.  These alternate names are useful in library
+header files in case they are included into files that have

This rewrapping seems unnecessary.

  redefined the base name of the attribute as a preprocessor macro.
+Similarly for every supported standard or scoped attribute, for example, the
+variant spellings of @code{[[gnu::weak]]} are @code{[[__gnu__::__weak__]]},
+@code{[[gnu::__weak__]]} or @code{[[__gnu__::weak]]}.  The only exception
+is that alternate spelling of the @code{clang} scoped attribute namespace
+is @code{_Clang} rather than @code{__clang__} for compatibility with that
+compiler.
GCC also accepts the keyword @code{__attribute} as a synonym for
  @code{__attribute__}.

@@ -33311,6 +33312,16 @@ cp_parser_std_attribute (cp_parser *pars
    cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
+  auto canonicalize_attr_ns_name = [] (tree attr_ns) {

{ on next line.

OK with those tweaks.

Jason

Reply via email to