[libcxx-commits] [libcxx] [libc++][ios] Applied `[[nodiscard]]` (PR #173520)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Dec 24 18:54:51 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.htm
- https://wg21.link/iostreams.base
---
Full diff: https://github.com/llvm/llvm-project/pull/173520.diff
3 Files Affected:
- (modified) libcxx/include/__ios/fpos.h (+5-5)
- (modified) libcxx/include/ios (+24-24)
- (added) libcxx/test/libcxx/input.output/iostreams.base/nodiscard.verify.cpp (+74)
``````````diff
diff --git a/libcxx/include/__ios/fpos.h b/libcxx/include/__ios/fpos.h
index e5c21b439188c..655158c6f2d89 100644
--- a/libcxx/include/__ios/fpos.h
+++ b/libcxx/include/__ios/fpos.h
@@ -28,9 +28,9 @@ class fpos {
public:
_LIBCPP_HIDE_FROM_ABI fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
- _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI operator streamoff() const { return __off_; }
- _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _StateT state() const { return __st_; }
_LIBCPP_HIDE_FROM_ABI void state(_StateT __st) { __st_ = __st; }
_LIBCPP_HIDE_FROM_ABI fpos& operator+=(streamoff __off) {
@@ -38,7 +38,7 @@ class fpos {
return *this;
}
- _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fpos operator+(streamoff __off) const {
fpos __t(*this);
__t += __off;
return __t;
@@ -49,7 +49,7 @@ class fpos {
return *this;
}
- _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fpos operator-(streamoff __off) const {
fpos __t(*this);
__t -= __off;
return __t;
@@ -57,7 +57,7 @@ class fpos {
};
template <class _StateT>
-inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {
return streamoff(__x) - streamoff(__y);
}
diff --git a/libcxx/include/ios b/libcxx/include/ios
index 78fc9d610987d..9295935079877 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -305,25 +305,25 @@ public:
class _LIBCPP_EXPORTED_FROM_ABI Init;
// 27.5.2.2 fmtflags state:
- _LIBCPP_HIDE_FROM_ABI fmtflags flags() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI fmtflags flags() const;
_LIBCPP_HIDE_FROM_ABI fmtflags flags(fmtflags __fmtfl);
_LIBCPP_HIDE_FROM_ABI fmtflags setf(fmtflags __fmtfl);
_LIBCPP_HIDE_FROM_ABI fmtflags setf(fmtflags __fmtfl, fmtflags __mask);
_LIBCPP_HIDE_FROM_ABI void unsetf(fmtflags __mask);
- _LIBCPP_HIDE_FROM_ABI streamsize precision() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize precision() const;
_LIBCPP_HIDE_FROM_ABI streamsize precision(streamsize __prec);
- _LIBCPP_HIDE_FROM_ABI streamsize width() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize width() const;
_LIBCPP_HIDE_FROM_ABI streamsize width(streamsize __wide);
// 27.5.2.3 locales:
locale imbue(const locale& __loc);
- locale getloc() const;
+ [[__nodiscard__]] locale getloc() const;
// 27.5.2.5 storage:
- static int xalloc();
- long& iword(int __index);
- void*& pword(int __index);
+ [[__nodiscard__]] static int xalloc();
+ [[__nodiscard__]] long& iword(int __index);
+ [[__nodiscard__]] void*& pword(int __index);
// destructor
virtual ~ios_base();
@@ -425,13 +425,13 @@ template <>
struct is_error_code_enum<io_errc::__lx> : public true_type {};
# endif
-_LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
+[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT;
-inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(io_errc __e) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(io_errc __e) _NOEXCEPT {
return error_code(static_cast<int>(__e), iostream_category());
}
-inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(io_errc __e) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(io_errc __e) _NOEXCEPT {
return error_condition(static_cast<int>(__e), iostream_category());
}
@@ -575,21 +575,21 @@ public:
# ifdef _LIBCPP_CXX03_LANG
// Preserve the ability to compare with literal 0,
// and implicitly convert to bool, but not implicitly convert to int.
- _LIBCPP_HIDE_FROM_ABI operator void*() const { return fail() ? nullptr : (void*)this; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI operator void*() const { return fail() ? nullptr : (void*)this; }
# else
- _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return !fail(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return !fail(); }
# endif
- _LIBCPP_HIDE_FROM_ABI bool operator!() const { return fail(); }
- _LIBCPP_HIDE_FROM_ABI iostate rdstate() const { return ios_base::rdstate(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool operator!() const { return fail(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate rdstate() const { return ios_base::rdstate(); }
_LIBCPP_HIDE_FROM_ABI void clear(iostate __state = goodbit) { ios_base::clear(__state); }
_LIBCPP_HIDE_FROM_ABI void setstate(iostate __state) { ios_base::setstate(__state); }
- _LIBCPP_HIDE_FROM_ABI bool good() const { return ios_base::good(); }
- _LIBCPP_HIDE_FROM_ABI bool eof() const { return ios_base::eof(); }
- _LIBCPP_HIDE_FROM_ABI bool fail() const { return ios_base::fail(); }
- _LIBCPP_HIDE_FROM_ABI bool bad() const { return ios_base::bad(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool good() const { return ios_base::good(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool eof() const { return ios_base::eof(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool fail() const { return ios_base::fail(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool bad() const { return ios_base::bad(); }
- _LIBCPP_HIDE_FROM_ABI iostate exceptions() const { return ios_base::exceptions(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iostate exceptions() const { return ios_base::exceptions(); }
_LIBCPP_HIDE_FROM_ABI void exceptions(iostate __iostate) { ios_base::exceptions(__iostate); }
// 27.5.4.1 Constructor/destructor:
@@ -597,21 +597,21 @@ public:
~basic_ios() override;
// 27.5.4.2 Members:
- _LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie() const;
_LIBCPP_HIDE_FROM_ABI basic_ostream<char_type, traits_type>* tie(basic_ostream<char_type, traits_type>* __tiestr);
- _LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf() const;
_LIBCPP_HIDE_FROM_ABI basic_streambuf<char_type, traits_type>* rdbuf(basic_streambuf<char_type, traits_type>* __sb);
basic_ios& copyfmt(const basic_ios& __rhs);
- _LIBCPP_HIDE_FROM_ABI char_type fill() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type fill() const;
_LIBCPP_HIDE_FROM_ABI char_type fill(char_type __ch);
_LIBCPP_HIDE_FROM_ABI locale imbue(const locale& __loc);
- _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const;
- _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const;
protected:
_LIBCPP_HIDE_FROM_ABI basic_ios() {
diff --git a/libcxx/test/libcxx/input.output/iostreams.base/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/iostreams.base/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..22245a8530f4a
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/iostreams.base/nodiscard.verify.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <ios>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <cwchar>
+#include <ios>
+
+#include "test_macros.h"
+
+void test() {
+ class test_stream : public std::ios {
+ public:
+ test_stream() { init(0); }
+ };
+ test_stream stream;
+
+ {
+ std::ios_base& ref = stream;
+
+ ref.flags(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.precision(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.width(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.getloc(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ios_base::xalloc();
+ ref.iword(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.pword(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::ios& ref = stream;
+
+#if TEST_STD_VER >= 11
+ ref.operator bool(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#else
+ ref.operator void*(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ !ref; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.rdstate(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.good(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.eof(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.fail(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.bad(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.exceptions(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ ref.tie(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.rdbuf(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ ref.fill(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ref.narrow('\0', '\0');
+ ref.widen('\0'); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::fpos<std::mbstate_t> pos;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pos.operator std::streamoff();
+ pos.state(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pos + std::streamoff(0);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ pos - std::streamoff(0);
+ pos - pos; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/173520
More information about the libcxx-commits
mailing list