Add support for C23 standard attributes using __has_c_attribute()

The __has_cpp_attribute() refers to the attributes supported by the C++
language. GCC returns its knowledge of the C++ attribute in C, even when
the C code doesn't support it.

N2335[1] added the C++ attribute syntax to the C language and N2553[2] added
the __has_c_attribute() query syntax.

Known attributes:
From https://en.cppreference.com/w/c/language/attributes#Standard_attributes:
* [[deprecated]] (from N2334)
* [[fallthrough]] (from N2408)
* [[nodiscard]] (from N2267, with message in N2448)
* [[maybe_unused]] (from N2662)
* [[noreturn]] (from N2764, which also deprecates _Noreturn)

Drive-by remove C++11 & 14 support from [[nodiscard]]

[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2335.pdf
[2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2553.pdf

Change-Id: Ifd32b2557683218e0d26fffd5b58dedf7911f77a
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 4cd66686e4fcf31ca1c8038c11125f90dc0b4782)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2025-04-02 16:59:10 -07:00 committed by Qt Cherry-pick Bot
parent 61369b37e1
commit bbe0b18b38

View File

@ -440,6 +440,9 @@
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
#ifndef __has_c_attribute
# define __has_c_attribute(x) 0
#endif
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#endif
@ -957,18 +960,19 @@
# endif
#endif
#if __has_cpp_attribute(nodiscard) && (!defined(Q_CC_CLANG) || __cplusplus > 201402L) // P0188R1
// Can't use [[nodiscard]] with Clang and C++11/14, see https://bugs.llvm.org/show_bug.cgi?id=33518
#if (defined(__cplusplus) && __has_cpp_attribute(nodiscard) /* P0188R1 */) || \
(!defined(__cplusplus) && __has_c_attribute(nodiscard) /* N2267 */)
# undef Q_REQUIRED_RESULT
# define Q_REQUIRED_RESULT [[nodiscard]]
#endif
#if __has_cpp_attribute(nodiscard) >= 201907L /* used for both P1771 and P1301... */
#if (defined(__cplusplus) && __has_cpp_attribute(nodiscard) >= 201907L /* used for both P1771 and P1301... */) \
|| (!defined(__cplusplus) && __has_c_attribute(nodiscard) /* N2448 */)
// [[nodiscard]] constructor (P1771)
# ifndef Q_NODISCARD_CTOR
# define Q_NODISCARD_CTOR [[nodiscard]]
# endif
// [[nodiscard("reason")]] (P1301)
// [[nodiscard("reason")]] (P1301, N2448 for C)
# ifndef Q_NODISCARD_X
# define Q_NODISCARD_X(message) [[nodiscard(message)]]
# endif
@ -977,17 +981,20 @@
# endif
#endif
#if __has_cpp_attribute(maybe_unused)
#if (defined(__cplusplus) && __has_cpp_attribute(maybe_unused)) || \
(!defined(__cplusplus) && __has_c_attribute(maybe_unused))
# undef Q_DECL_UNUSED
# define Q_DECL_UNUSED [[maybe_unused]]
#endif
#if __has_cpp_attribute(noreturn)
#if (defined(__cplusplus) && __has_cpp_attribute(noreturn)) || \
(!defined(__cplusplus) && __has_c_attribute(noreturn))
# undef Q_NORETURN
# define Q_NORETURN [[noreturn]]
#endif
#if __has_cpp_attribute(deprecated)
#if (defined(__cplusplus) && __has_cpp_attribute(deprecated)) || \
(!defined(__cplusplus) && __has_c_attribute(deprecated))
# ifdef Q_DECL_DEPRECATED
# undef Q_DECL_DEPRECATED
# endif
@ -1257,7 +1264,11 @@
#elif __has_cpp_attribute(fallthrough)
# define Q_FALLTHROUGH() [[fallthrough]]
#endif
#endif
#else // !defined(__cplusplus)
# if __has_c_attribute(fallthrough)
# define Q_FALLTHROUGH() [[fallthrough]]
# endif
#endif // !defined(__cplusplus)
#ifndef Q_FALLTHROUGH
# ifdef Q_CC_GNU
# define Q_FALLTHROUGH() __attribute__((fallthrough))