Skip to content

Conversation

@H-G-Hristov
Copy link
Contributor

[[nodiscard]] should be applied to functions where discarding the return value is most likely a correctness issue.

@github-actions
Copy link

github-actions bot commented Dec 8, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-filesystem branch 10 times, most recently from 17aa146 to ca708a0 Compare December 10, 2025 10:18
@H-G-Hristov
Copy link
Contributor Author

`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html
@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/nodiscard-to-filesystem branch from ca708a0 to ad6f10f Compare December 10, 2025 11:44
@H-G-Hristov H-G-Hristov marked this pull request as ready for review December 10, 2025 17:48
@H-G-Hristov H-G-Hristov requested a review from a team as a code owner December 10, 2025 17:48
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2025

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

Changes

[[nodiscard]] should be applied to functions where discarding the return value is most likely a correctness issue.


Patch is 76.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/171085.diff

15 Files Affected:

  • (modified) libcxx/include/__filesystem/copy_options.h (+7-7)
  • (modified) libcxx/include/__filesystem/directory_entry.h (+37-29)
  • (modified) libcxx/include/__filesystem/directory_iterator.h (+7-3)
  • (modified) libcxx/include/__filesystem/directory_options.h (+7-4)
  • (modified) libcxx/include/__filesystem/file_status.h (+2-2)
  • (modified) libcxx/include/__filesystem/filesystem_error.h (+6-5)
  • (modified) libcxx/include/__filesystem/operations.h (+97-62)
  • (modified) libcxx/include/__filesystem/path.h (+61-55)
  • (modified) libcxx/include/__filesystem/path_iterator.h (+1-1)
  • (modified) libcxx/include/__filesystem/perm_options.h (+4-4)
  • (modified) libcxx/include/__filesystem/perms.h (+4-4)
  • (modified) libcxx/include/__filesystem/recursive_directory_iterator.h (+7-6)
  • (modified) libcxx/include/__filesystem/u8path.h (+3-3)
  • (modified) libcxx/test/libcxx/diagnostics/filesystem.nodiscard.verify.cpp (+440-4)
  • (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp (+1-1)
diff --git a/libcxx/include/__filesystem/copy_options.h b/libcxx/include/__filesystem/copy_options.h
index 097eebe61137d..cba719dbed1f6 100644
--- a/libcxx/include/__filesystem/copy_options.h
+++ b/libcxx/include/__filesystem/copy_options.h
@@ -34,31 +34,31 @@ enum class copy_options : unsigned short {
   __in_recursive_copy = 512,
 };
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
   return static_cast<copy_options>(static_cast<unsigned short>(__lhs) & static_cast<unsigned short>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
   return static_cast<copy_options>(static_cast<unsigned short>(__lhs) | static_cast<unsigned short>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
   return static_cast<copy_options>(static_cast<unsigned short>(__lhs) ^ static_cast<unsigned short>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
   return static_cast<copy_options>(~static_cast<unsigned short>(__lhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) {
   return __lhs = __lhs & __rhs;
 }
 
-_LIBCPP_HIDE_FROM_ABI inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) {
   return __lhs = __lhs | __rhs;
 }
 
-_LIBCPP_HIDE_FROM_ABI inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) {
   return __lhs = __lhs ^ __rhs;
 }
 
diff --git a/libcxx/include/__filesystem/directory_entry.h b/libcxx/include/__filesystem/directory_entry.h
index 3513a4975ad8f..fab400b439429 100644
--- a/libcxx/include/__filesystem/directory_entry.h
+++ b/libcxx/include/__filesystem/directory_entry.h
@@ -87,80 +87,88 @@ class directory_entry {
 
   _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); }
 
-  _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; }
 
   _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; }
 
-  _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); }
 
-  _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept {
     return filesystem::exists(file_status{__get_ft(&__ec)});
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept {
     return __get_ft(&__ec) == file_type::block;
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept {
     return __get_ft(&__ec) == file_type::character;
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept {
     return __get_ft(&__ec) == file_type::directory;
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::fifo;
+  }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept {
     return filesystem::is_other(file_status{__get_ft(&__ec)});
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept {
     return __get_ft(&__ec) == file_type::regular;
   }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept {
+    return __get_ft(&__ec) == file_type::socket;
+  }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; }
 
-  _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept {
     return __get_sym_ft(&__ec) == file_type::symlink;
   }
-  _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); }
 
-  _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); }
 
-  _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); }
 
-  _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept {
+    return __get_nlink(&__ec);
+  }
 
-  _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); }
 
-  _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept {
     return __get_write_time(&__ec);
   }
 
-  _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); }
 
-  _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept {
+    return __get_status(&__ec);
+  }
 
-  _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); }
 
-  _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept {
     return __get_symlink_status(&__ec);
   }
 
diff --git a/libcxx/include/__filesystem/directory_iterator.h b/libcxx/include/__filesystem/directory_iterator.h
index 5e9fea636de0b..b62129807b567 100644
--- a/libcxx/include/__filesystem/directory_iterator.h
+++ b/libcxx/include/__filesystem/directory_iterator.h
@@ -71,7 +71,7 @@ class directory_iterator {
 
   _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default;
 
-  _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const {
     // Note: this check duplicates a check in `__dereference()`.
     _LIBCPP_ASSERT_NON_NULL(__imp_, "The end iterator cannot be dereferenced");
     return __dereference();
@@ -121,9 +121,13 @@ operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) noe
 }
 
 // enable directory_iterator range-based for statements
-inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept { return __iter; }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept {
+  return __iter;
+}
 
-inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept { return directory_iterator(); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept {
+  return directory_iterator();
+}
 
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 
diff --git a/libcxx/include/__filesystem/directory_options.h b/libcxx/include/__filesystem/directory_options.h
index d0cd3ebfdaa7e..11c7d204ea824 100644
--- a/libcxx/include/__filesystem/directory_options.h
+++ b/libcxx/include/__filesystem/directory_options.h
@@ -22,19 +22,22 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
 
 enum class directory_options : unsigned char { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2 };
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator&(directory_options __lhs, directory_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
+operator&(directory_options __lhs, directory_options __rhs) {
   return static_cast<directory_options>(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator|(directory_options __lhs, directory_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
+operator|(directory_options __lhs, directory_options __rhs) {
   return static_cast<directory_options>(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator^(directory_options __lhs, directory_options __rhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options
+operator^(directory_options __lhs, directory_options __rhs) {
   return static_cast<directory_options>(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs));
 }
 
-_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) {
   return static_cast<directory_options>(~static_cast<unsigned char>(__lhs));
 }
 
diff --git a/libcxx/include/__filesystem/file_status.h b/libcxx/include/__filesystem/file_status.h
index eecaf3c492f03..746cd0f9a680c 100644
--- a/libcxx/include/__filesystem/file_status.h
+++ b/libcxx/include/__filesystem/file_status.h
@@ -38,9 +38,9 @@ class file_status {
   _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept      = default;
 
   // observers
-  _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; }
 
-  _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; }
 
   // modifiers
   _LIBCPP_HIDE_FROM_ABI void type(file_type __ft) noexcept { __ft_ = __ft; }
diff --git a/libcxx/include/__filesystem/filesystem_error.h b/libcxx/include/__filesystem/filesystem_error.h
index 0df170f3d3a9f..6f1daf866a504 100644
--- a/libcxx/include/__filesystem/filesystem_error.h
+++ b/libcxx/include/__filesystem/filesystem_error.h
@@ -44,15 +44,16 @@ class _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error {
     __create_what(2);
   }
 
-  _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; }
 
-  _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; }
 
-  _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default;
   ~filesystem_error() override; // key function
 
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
-  const char* what() const noexcept override { return __storage_->__what_.c_str(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override {
+    return __storage_->__what_.c_str();
+  }
 
   void __create_what(int __num_paths);
 
diff --git a/libcxx/include/__filesystem/operations.h b/libcxx/include/__filesystem/operations.h
index 0fd55c19414c4..f536a1a9d4466 100644
--- a/libcxx/include/__filesystem/operations.h
+++ b/libcxx/include/__filesystem/operations.h
@@ -68,10 +68,14 @@ _LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec =
 _LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr);
 _LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr);
 
-inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
-inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); }
-inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); }
-inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) {
+  return __absolute(__p, &__ec);
+}
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) {
+  return __canonical(__p, &__ec);
+}
 inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) {
   return __copy_file(__from, __to, copy_options::none);
 }
@@ -135,85 +139,112 @@ inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const pat
 inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept {
   return __create_symlink(__target, __link, &__ec);
 }
-inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); }
-inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); }
 inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); }
 inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept {
   __current_path(__p, &__ec);
 }
-inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); }
-inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) {
+  return __equivalent(__p1, __p2);
+}
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool
+equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept {
   return __equivalent(__p1, __p2, &__ec);
 }
-inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; }
-inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept {
+  return __s.type() != file_type::none;
+}
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept {
   return status_known(__s) && __s.type() != file_type::not_found;
 }
-inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); }
 
-inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept {
   auto __s = __status(__p, &__ec);
   if (status_known(__s))
     __ec.clear();
   return exists(__s);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); }
-inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept {
   return __file_size(__p, &__ec);
 }
-inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
-inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept {
   return __hard_link_count(__p, &__ec);
 }
-inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; }
-inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
-inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept {
+  return __s.type() == file_type::block;
+}
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); }
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept {
   return is_block_file(__status(__p, &__ec));
 }
-inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept {
   return __s.type() == file_type::character;
 }
-inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { retur...
[truncated]

@@ -49,7 +49,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f,

# if defined(_LIBCPP_WIN32API) && _LIBCPP_HAS_LOCALIZATION
template <class _InputIt, __enable_if_t<__is_pathable<_InputIt>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) {
Copy link
Contributor

@frederick-vs-ja frederick-vs-ja Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly believe that this overload is non-conforming and should be removed (or reformed, but I strongly think that removal will be better). I think it would be better to avoid touching it, given it's not being tested. (No change strictly requested.)

{
const std::string str;

#if !defined(TEST_HAS_NO_LOCALIZATION)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested as fixed should be in a future PR. This is quite weird. If localization is unavailable, we should use non-transcoded strings as-is, so IMO these uses of u8path should be always available.

@Zingam Zingam merged commit c05a3ac into llvm:main Dec 12, 2025
83 checks passed
Comment on lines +37 to 51
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) {
return static_cast<copy_options>(static_cast<unsigned short>(__lhs) & static_cast<unsigned short>(__rhs));
}

_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) {
return static_cast<copy_options>(static_cast<unsigned short>(__lhs) | static_cast<unsigned short>(__rhs));
}

_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) {
return static_cast<copy_options>(static_cast<unsigned short>(__lhs) ^ static_cast<unsigned short>(__rhs));
}

_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) {
return static_cast<copy_options>(~static_cast<unsigned short>(__lhs));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why were these added? Clang should warn without any annotations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But currently Clang doesn't. Is there already a PR for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently Clang doesn't do that:
https://godbolt.org/z/36TGdT9a9

anonymouspc pushed a commit to anonymouspc/llvm that referenced this pull request Dec 15, 2025
`[[nodiscard]]` should be applied to functions where discarding the
return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants