Skip to content

[libc++] Don't use copy_file_impl_fstream when not declared - #214706

Open
AnthonyLatsis wants to merge 1 commit into
llvm:mainfrom
swiftlang:jepa-next2
Open

[libc++] Don't use copy_file_impl_fstream when not declared#214706
AnthonyLatsis wants to merge 1 commit into
llvm:mainfrom
swiftlang:jepa-next2

Conversation

@AnthonyLatsis

@AnthonyLatsis AnthonyLatsis commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

copy_file_impl_fstream is declared and defined only under _LIBCPP_FILESYSTEM_NEED_FSTREAM (which additionally requires _LIBCPP_HAS_LOCALIZATION), and then used in a copy_file_impl variant under a disjoint set of conditions. This causes any build that disables localization and elects this variant of copy_file_impl, as is currently the case when targeting wasi, to fail with a generic compiler error:

error: use of undeclared identifier 'copy_file_impl_fstream'

Instead, since this particular copy_file_impl implementation merely forwards to copy_file_impl_fstream, tweak its gating condition such that the aforementioned configuration hits the dedicated fallback branch, which offers a somewhat clearer error message:

#  error "Unknown implementation for copy_file_impl"

@AnthonyLatsis
AnthonyLatsis requested a review from a team as a code owner August 7, 2026 11:30
@llvmorg-github-actions llvmorg-github-actions Bot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 7, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-libcxx

Author: Anthony Latsis (AnthonyLatsis)

Changes

copy_file_impl_fstream is only defined under
_LIBCPP_FILESYSTEM_NEED_FSTREAM, which additionally requires _LIBCPP_HAS_LOCALIZATION. The _LIBCPP_FILESYSTEM_USE_FSTREAM dispatch called it unconditionally, so a build with filesystem enabled and localization disabled failed on any platform that provides neither sendfile nor copyfile:

error: use of undeclared identifier 'copy_file_impl_fstream'

Report EINVAL instead, as the sendfile/copy_file_range dispatch above already does in the same situation.

Assisted-by: Claude Code


Full diff: https://github.com/llvm/llvm-project/pull/214706.diff

1 Files Affected:

  • (modified) libcxx/src/filesystem/operations.cpp (+6)
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 3ff62c102d0ad..7099cd2c75ab6 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -362,7 +362,13 @@ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_cod
 }
 #elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)
 bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) {
+#  if defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)
   return copy_file_impl_fstream(read_fd, write_fd, ec);
+#  else
+  // iostreams are unavailable in the no-locale build, just fail.
+  ec.assign(EINVAL, std::system_category());
+  return false;
+#  endif
 }
 #else
 #  error "Unknown implementation for copy_file_impl"

@AnthonyLatsis

Copy link
Copy Markdown
Contributor Author

cc @hamishknight

Comment thread libcxx/src/filesystem/operations.cpp Outdated
`copy_file_impl_fstream` is declared and defined only under
`_LIBCPP_FILESYSTEM_NEED_FSTREAM` (which additionally requires
`_LIBCPP_HAS_LOCALIZATION`), and then used in a `copy_file_impl`
variant under a disjoint set of conditions. This causes any build that
disables localization and elects this variant of `copy_file_impl`, as is
currently the case when targeting wasi, to fail with a generic compiler
error:

```
error: use of undeclared identifier 'copy_file_impl_fstream'
```

Instead, since this particular `copy_file_impl` implementation merely
forwards to `copy_file_impl_fstream`, tweak its gating condition such
that the aforementioned configuration hits the dedicated fallback
branch, which offers a somewhat clearer error message:

```
\#  error "Unknown implementation for copy_file_impl"
```
@AnthonyLatsis AnthonyLatsis changed the title [libc++] Fix insufficiently guarded call to copy_file_impl_fstream [libc++] Don't use copy_file_impl_fstream when not declared Aug 11, 2026

@ldionne ldionne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find the #elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) && defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM) conditional a bit odd, but I think that's because of the name _LIBCPP_FILESYSTEM_NEED_FSTREAM.

I made some suggestions on the PR, let me know what you think about them. I can live with either way but I think the larger refactoring I suggest leaves us with something a bit clearer.

Comment on lines 58 to 65
// sendfile and copy_file_range need to fall back
// to the fstream implementation for special files
#if (defined(_LIBCPP_FILESYSTEM_USE_SENDFILE) || defined(_LIBCPP_FILESYSTEM_USE_COPY_FILE_RANGE) || \
defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)) && \
_LIBCPP_HAS_LOCALIZATION
# include <fstream>
# define _LIBCPP_FILESYSTEM_NEED_FSTREAM
#endif

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
// sendfile and copy_file_range need to fall back
// to the fstream implementation for special files
#if _LIBCPP_HAS_LOCALIZATION
# include <fstream>
# define _LIBCPP_FILESYSTEM_HAS_FSTREAM_FALLBACK
#endif

namespace detail {
namespace {

#if defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#if defined(_LIBCPP_FILESYSTEM_HAS_FSTREAM_FALLBACK)

ec.clear();
# endif

# if defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# if defined(_LIBCPP_FILESYSTEM_HAS_FSTREAM_FALLBACK)

return true;
}
#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)
#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) && defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) && defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)
#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)

#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)
#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM) && defined(_LIBCPP_FILESYSTEM_NEED_FSTREAM)
bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) {
return copy_file_impl_fstream(read_fd, write_fd, ec);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
return copy_file_impl_fstream(read_fd, write_fd, ec);
# if !defined(_LIBCPP_FILESYSTEM_HAS_FSTREAM_FALLBACK)
# error copy_file intends to use std::fstream as a fallback, but std::fstream is not available in this configuration
# endif
return copy_file_impl_fstream(read_fd, write_fd, ec);

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.

2 participants