https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93201
Bug ID: 93201 Summary: std::filesystem::remove_all fails to remove large files Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <fstream> #include <filesystem> int main(int argc, char** argv) { if (argc < 2) return 1; std::filesystem::path dir(argv[1]); std::error_code ec; create_directory(dir, ec); // ignore errors std::ofstream file{dir/"file"}; std::string s; s.resize(1 << 20); for (unsigned i = 1 << 12; i; --i) file.write(s.data(), s.size()); remove_all(dir); } With GCC 9 this fails to remove the directory: tmp$ ./a.out out terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: cannot remove all: Directory not empty [out] Aborted (core dumped) tmp$ ls -l out total 4194304 -rw-rw-r--. 1 jwakely jwakely 4294967296 Jan 8 12:01 file The problem is that remove_all("dir/file", ec) calls status("dir/file", ec) which fails (with the same error as PR 91947 comment 2), but then the call to d.increment(ec) clears the error_code: if (s.type() == file_type::directory) { for (directory_iterator d(p, ec), end; !ec && d != end; d.increment(ec)) count += fs::remove_all(d->path(), ec); if (ec.value() == ENOENT) ec.clear(); else if (ec) return -1; } This means that the "if (ec)" test only ever fails if d.increment(ec) encounters an error. The testcase works correctly on trunk because std::filesystem is built with LFS, but the remove_all bug that clears the error_code is still latent on trunk.