[libcxx-commits] [libcxx] [libc++][iostream] Applied `[[nodiscard]]` (PR #173754)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Dec 28 06:56:16 PST 2025
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/173754
>From 61ca986bfb30a997defccbf09a335384ad594ce1 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 27 Dec 2025 07:25:10 +0200
Subject: [PATCH 1/5] [libc++][iostream] Applied `[[nodiscard]]`
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- [x] `basic_streambuf`
- [x] `basic_istream`
- [x] `basic_ostream`
- [x] `basic_iostream`
- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/stream.buffers
- https://wg21.link/iostreamclass
- https://wg21.link/istream
- https://wg21.link/ostream
Towards #172124
---
libcxx/include/__ostream/basic_ostream.h | 2 +-
libcxx/include/istream | 8 ++--
libcxx/include/streambuf | 8 ++--
.../iostream.format/nodiscard.verify.cpp | 46 +++++++++++++++++++
.../stream.buffers/nodiscard.verify.cpp | 29 ++++++++++++
5 files changed, 84 insertions(+), 9 deletions(-)
create mode 100644 libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
diff --git a/libcxx/include/__ostream/basic_ostream.h b/libcxx/include/__ostream/basic_ostream.h
index effeef491f341..4fa8abc6fcf92 100644
--- a/libcxx/include/__ostream/basic_ostream.h
+++ b/libcxx/include/__ostream/basic_ostream.h
@@ -174,7 +174,7 @@ class basic_ostream : virtual public basic_ios<_CharT, _Traits> {
basic_ostream& flush();
// 27.7.2.5 seeks:
- inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp();
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp();
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(pos_type __pos);
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
diff --git a/libcxx/include/istream b/libcxx/include/istream
index 7f15521f91a8a..8d42f2fa08241 100644
--- a/libcxx/include/istream
+++ b/libcxx/include/istream
@@ -265,8 +265,8 @@ public:
basic_istream& operator>>(void*& __p);
// 27.7.1.3 Unformatted input:
- _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
- int_type get();
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
+ [[__nodiscard__]] int_type get();
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) {
int_type __ch = get();
@@ -298,7 +298,7 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_istream& ignore(streamsize __n, char_type __delim) {
return ignore(__n, traits_type::to_int_type(__delim));
}
- int_type peek();
+ [[__nodiscard__]] int_type peek();
basic_istream& read(char_type* __s, streamsize __n);
streamsize readsome(char_type* __s, streamsize __n);
@@ -306,7 +306,7 @@ public:
basic_istream& unget();
int sync();
- pos_type tellg();
+ [[__nodiscard__]] pos_type tellg();
basic_istream& seekg(pos_type __pos);
basic_istream& seekg(off_type __off, ios_base::seekdir __dir);
};
diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf
index 7dc4e31cc2324..be790ffca1447 100644
--- a/libcxx/include/streambuf
+++ b/libcxx/include/streambuf
@@ -157,7 +157,7 @@ public:
return __r;
}
- inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }
// 27.6.2.2.2 buffer and positioning:
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
@@ -178,7 +178,7 @@ public:
// Get and put areas:
// 27.6.2.2.3 Get area:
- inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
__check_invariants();
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
@@ -187,7 +187,7 @@ public:
return showmanyc();
}
- inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
__check_invariants();
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
@@ -207,7 +207,7 @@ public:
return __c;
}
- inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
+ [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
__check_invariants();
auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });
diff --git a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..940692d298896
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <istream>
+// <ostream>
+// <iostream>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <iostream>
+
+void test() {
+ // [iostreamclass]
+
+ // [istream]
+
+ {
+ std::basic_istream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.gcount();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.get();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.peek();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.tellg();
+ }
+
+ // [ostream]
+
+ {
+ std::basic_ostream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.tellp();
+ }
+}
diff --git a/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..d95a753341ca8
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <streambuf>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <streambuf>
+
+void test() {
+ std::basic_streambuf<char> sbuf;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sbuf.getloc();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sbuf.in_avail();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sbuf.snextc();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sbuf.sgetc();
+}
>From 96922f5749edb737c4201870722f697e815e1297 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 28 Dec 2025 08:15:18 +0200
Subject: [PATCH 2/5] Fixed CI
---
libcxx/include/istream | 2 +-
.../libcxx/input.output/iostream.format/nodiscard.verify.cpp | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/libcxx/include/istream b/libcxx/include/istream
index 8d42f2fa08241..6b8a339d73233 100644
--- a/libcxx/include/istream
+++ b/libcxx/include/istream
@@ -266,7 +266,7 @@ public:
// 27.7.1.3 Unformatted input:
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
- [[__nodiscard__]] int_type get();
+ int_type get();
inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) {
int_type __ch = get();
diff --git a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
index 940692d298896..e6260a7826f9d 100644
--- a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
@@ -25,9 +25,6 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.gcount();
- // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
- stream.get();
-
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.peek();
>From 6e035c419038a1befff29d117f69ecb37d619777 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 28 Dec 2025 08:31:00 +0200
Subject: [PATCH 3/5] Fix CI
---
.../input.output/iostream.format/nodiscard.verify.cpp | 11 +++++++++--
.../input.streams/istream.unformatted/peek.pass.cpp | 4 ++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
index e6260a7826f9d..c54232d5133a0 100644
--- a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
@@ -14,13 +14,20 @@
#include <iostream>
+struct testbuf
+ : public std::basic_streambuf<char>
+{};
+
+
void test() {
+ testbuf sbuf;
+
// [iostreamclass]
// [istream]
{
- std::basic_istream<char> stream;
+ std::basic_istream<char> stream(sbuf);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.gcount();
@@ -35,7 +42,7 @@ void test() {
// [ostream]
{
- std::basic_ostream<char> stream;
+ std::basic_ostream<char> stream(sbuf);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.tellp();
diff --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
index 450f2f1d5e34d..91af5a3ad2393 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
@@ -77,7 +77,7 @@ int main(int, char**)
is.exceptions(std::ios_base::eofbit);
bool threw = false;
try {
- is.peek();
+ (void)is.peek();
} catch (std::ios_base::failure&) {
threw = true;
}
@@ -93,7 +93,7 @@ int main(int, char**)
is.exceptions(std::ios_base::eofbit);
bool threw = false;
try {
- is.peek();
+ (void)is.peek();
} catch (std::ios_base::failure&) {
threw = true;
}
>From 06e6bffe510fac43e6a0f8767629002e3d0744cb Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 28 Dec 2025 08:34:04 +0200
Subject: [PATCH 4/5] Fix CI
---
.../input.streams/istream.unformatted/peek.pass.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
index 91af5a3ad2393..3fd051bfe0e4c 100644
--- a/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
@@ -77,7 +77,7 @@ int main(int, char**)
is.exceptions(std::ios_base::eofbit);
bool threw = false;
try {
- (void)is.peek();
+ (void)is.peek();
} catch (std::ios_base::failure&) {
threw = true;
}
@@ -93,7 +93,7 @@ int main(int, char**)
is.exceptions(std::ios_base::eofbit);
bool threw = false;
try {
- (void)is.peek();
+ (void)is.peek();
} catch (std::ios_base::failure&) {
threw = true;
}
>From eaa07fd2cf02c1eec8e733ca7bf4a2c694c61609 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 28 Dec 2025 16:55:59 +0200
Subject: [PATCH 5/5] Final fix
---
.../iostream.format/nodiscard.verify.cpp | 12 ++++--------
.../input.output/stream.buffers/nodiscard.verify.cpp | 3 ++-
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
index c54232d5133a0..959e99fb89098 100644
--- a/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/input.output/iostream.format/nodiscard.verify.cpp
@@ -14,20 +14,16 @@
#include <iostream>
-struct testbuf
- : public std::basic_streambuf<char>
-{};
-
-
void test() {
- testbuf sbuf;
+ struct testbuf : public std::basic_streambuf<char> {
+ } sbuf;
// [iostreamclass]
// [istream]
{
- std::basic_istream<char> stream(sbuf);
+ std::basic_istream<char> stream(&sbuf);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.gcount();
@@ -42,7 +38,7 @@ void test() {
// [ostream]
{
- std::basic_ostream<char> stream(sbuf);
+ std::basic_ostream<char> stream(&sbuf);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
stream.tellp();
diff --git a/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
index d95a753341ca8..0bb8bba566c3d 100644
--- a/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/input.output/stream.buffers/nodiscard.verify.cpp
@@ -13,7 +13,8 @@
#include <streambuf>
void test() {
- std::basic_streambuf<char> sbuf;
+ struct testbuf : public std::basic_streambuf<char> {
+ } sbuf;
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sbuf.getloc();
More information about the libcxx-commits
mailing list