From bbe0b18b382b16b13d38797d69abbd12f9021aed Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 2 Apr 2025 16:59:10 -0700 Subject: [PATCH] Add support for C23 standard attributes using __has_c_attribute() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 4cd66686e4fcf31ca1c8038c11125f90dc0b4782) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/global/qcompilerdetection.h | 27 +++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index df27cbf10c8..3d85f711ea0 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -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))