Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 May 2025 04:30:23 GMT
From:      Lexi Winter <ivy@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: cf47e6d4e14a - stable/14 - sys/cdefs.h: add __nodiscard annotation
Message-ID:  <202505190430.54J4UNKh059573@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by ivy:

URL: https://cgit.FreeBSD.org/src/commit/?id=cf47e6d4e14ab97d42317cb653926a0b6f9a21e9

commit cf47e6d4e14ab97d42317cb653926a0b6f9a21e9
Author:     Lexi Winter <ivy@FreeBSD.org>
AuthorDate: 2025-05-09 21:28:14 +0000
Commit:     Lexi Winter <ivy@FreeBSD.org>
CommitDate: 2025-05-19 03:04:26 +0000

    sys/cdefs.h: add __nodiscard annotation
    
    __nodiscard adds the [[nodiscard]] attribute to a function, type or
    constructor in C or C++, causing a value so marked to issue a compiler
    warning if it is discarded (i.e., not used or assigned) other than by
    casting it to void.
    
    this replaces the existing __result_use_or_ignore_check, which has a
    similar purpose but different semantics.  since __nodiscard provides
    more functionality (at least in GCC) and __result_use_or_ignore_check
    only had a single user, remove __result_use_or_ignore_check.
    
    [[nodiscard]] has been supported in C++ since C++17, but only in C since
    C23; however, both LLVM and GCC implement it even in older language
    versions, so it should always be available with a relatively modern
    compiler.
    
    for Clang, [[nodiscard]] in C is only available since LLVM 17, but we
    can fall back to __attribute__((__warn_unused_result__)) which has the
    same semantics and provides support back to (at least) LLVM 11.
    
    GCC supports [[nodiscard]] in both C and C++ since at least GCC 11.
    for GCC, we can't provide a fallback as the semantics of its
    warn_unused_result are different, but since __result_use_or_ignore_check
    isn't defined for GCC anyway, we don't lose anything here.
    
    MFC after:      2 weeks
    Reviewed by:    des, emaste
    Approved by:    des (mentor)
    Differential Revision:  https://reviews.freebsd.org/D50217
    
    (cherry picked from commit 7e0c5e0128c43bbae78190911aead8e1d9475ba5)
---
 sys/sys/cdefs.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index dc5221343dc3..209acc842839 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -393,6 +393,44 @@
 #endif
 #endif
 
+/*
+ * nodiscard attribute added in C++17 and C23, but supported by both LLVM and
+ * GCC in earlier language versions, so we use __has_c{,pp}_attribute to test
+ * for it.
+ *
+ * __nodiscard may be used on a function:
+ * 	__nodiscard int f();
+ *
+ * or on a struct, union or enum:
+ * 	struct __nodiscard S{};
+ * 	struct S f();
+ *
+ * or in C++, on an object constructor.
+ */
+
+#if defined(__cplusplus) && defined(__has_cpp_attribute)
+#if __has_cpp_attribute(nodiscard)
+#define	__nodiscard	[[nodiscard]]
+#endif
+#elif defined(__STDC_VERSION__) && defined(__has_c_attribute)
+#if __has_c_attribute(__nodiscard__)
+#define	__nodiscard	[[__nodiscard__]]
+#endif
+#endif
+
+#ifndef __nodiscard
+/*
+ * LLVM 16 and earlier don't support [[nodiscard]] in C, but they do support
+ * __warn_unused_result__ with the same semantics, so fall back to that.
+ * We can't do this for GCC because the semantics are different.
+ */
+#ifdef __clang__
+#define	__nodiscard	__attribute__((__warn_unused_result__))
+#else
+#define	__nodiscard
+#endif
+#endif
+
 /*
  * We use `__restrict' as a way to define the `restrict' type qualifier
  * without disturbing older software that is unaware of C99 keywords.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505190430.54J4UNKh059573>