On 7/9/26 3:33 PM, Jakub Jelinek wrote:
On Thu, Jul 09, 2026 at 11:31:12AM -0400, Jason Merrill wrote:
And it is even documented like that.
The special operator @code{__has_cpp_attribute (@var{operand})} may be used
in @samp{#if} and @samp{#elif} expressions in C++ code to test whether
the attribute referenced by its @var{operand} is recognized by GCC.
@code{__has_cpp_attribute (@var{operand})} is equivalent to
@code{__has_attribute (@var{operand})} except that when @var{operand}
designates a supported standard attribute it evaluates to an integer
constant of the form @code{YYYYMM} indicating the year and month when
the attribute was first introduced into the C++ standard.
The "except that when @var{operand} ... " part is misleading because
__has_attribute behaves exactly like that too.

Looking at clang++, that behaves differently, doesn't allow scoped
attributes in __has_attribute at all (just __has_cpp_attribute and
__has_c_attribute) and __has_cpp_attribute (trivial_abi) is 0
and __has_attribute (trivial_abi) is 1.
Yes, that's the behavior I would expect.

And for this patch I'm just asking that we not test for the wrong answer.

Ok, here it is with different expected value and dg-bogus xfailed for now.

OK.
2026-07-09  Jakub Jelinek  <[email protected]>

        PR c++/107187
        * c-lex.cc (c_common_has_attribute): Don't advertise
        __has_cpp_attribute (gnu::trivial_abi) in C++.

        * g++.dg/cpp0x/attr-trivial_abi8.C: New test.

--- gcc/c-family/c-lex.cc.jj    2026-04-28 08:54:25.377643162 +0200
+++ gcc/c-family/c-lex.cc       2026-07-08 18:47:10.790872988 +0200
@@ -403,6 +403,13 @@ c_common_has_attribute (cpp_reader *pfil
                result = 1;
              if (result)
                attr_name = NULL_TREE;
+             /* gnu::trivial_abi is in the attribute table just
+                to error on it and suggest using [[clang::trivial_abi]]
+                or __attribute__((trivial_abi)).  Don't advertise it.  */
+             else if (c_dialect_cxx ()
+                      && is_attribute_p ("gnu", attr_ns)
+                      && is_attribute_p ("trivial_abi", attr_id))
+               attr_name = NULL_TREE;
              else
                attr_name = build_tree_list (attr_ns, attr_id);
            }
--- gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi8.C.jj   2026-07-08 
18:49:01.145455196 +0200
+++ gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi8.C      2026-07-09 
21:29:53.506097751 +0200
@@ -0,0 +1,21 @@
+// { dg-do preprocess { target c++11 } }
+
+#if __has_cpp_attribute (clang::trivial_abi) != 1
+#error
+#endif
+#if __has_cpp_attribute (gnu::trivial_abi) != 0
+#error
+#endif
+#if __has_cpp_attribute (trivial_abi) != 0
+#error This fails for now
+// { dg-bogus "This fails for now" "" { xfail *-*-* } .-1 }
+#endif
+#if __has_attribute (clang::trivial_abi) != 1
+#error
+#endif
+#if __has_attribute (gnu::trivial_abi) != 0
+#error
+#endif
+#if __has_attribute (trivial_abi) != 1
+#error
+#endif


        Jakub


Reply via email to