From 3084c7a0593441530fceb01544425bafa0fca261 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Mon, 9 Dec 2024 00:07:33 +0400 Subject: [PATCH 1/3] [Support] Use std::filesystem::remove_all() in remove_directories() See #118677 for details. --- llvm/lib/Support/Path.cpp | 8 +++++++ llvm/lib/Support/Unix/Path.inc | 40 ------------------------------- llvm/lib/Support/Windows/Path.inc | 26 -------------------- 3 files changed, 8 insertions(+), 66 deletions(-) diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index d775285197103..4c0804f2dd494 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include +#include #if !defined(_MSC_VER) && !defined(__MINGW32__) #include @@ -1206,6 +1207,13 @@ namespace llvm { namespace sys { namespace fs { +std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { + const std::filesystem::path Path(path.str()); + std::error_code EC; + std::filesystem::remove_all(Path, EC); + return IgnoreErrors ? std::error_code() : EC; +} + TempFile::TempFile(StringRef Name, int FD) : TmpName(std::string(Name)), FD(FD) {} TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); } diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 44097bad7b46e..b8cc6b8bdb464 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -1272,46 +1272,6 @@ std::error_code closeFile(file_t &F) { return Process::SafelyCloseFileDescriptor(TmpF); } -template -static std::error_code remove_directories_impl(const T &Entry, - bool IgnoreErrors) { - std::error_code EC; - directory_iterator Begin(Entry, EC, false); - directory_iterator End; - while (Begin != End) { - auto &Item = *Begin; - ErrorOr st = Item.status(); - if (st) { - if (is_directory(*st)) { - EC = remove_directories_impl(Item, IgnoreErrors); - if (EC && !IgnoreErrors) - return EC; - } - - EC = fs::remove(Item.path(), true); - if (EC && !IgnoreErrors) - return EC; - } else if (!IgnoreErrors) { - return st.getError(); - } - - Begin.increment(EC); - if (EC && !IgnoreErrors) - return EC; - } - return std::error_code(); -} - -std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { - auto EC = remove_directories_impl(path, IgnoreErrors); - if (EC && !IgnoreErrors) - return EC; - EC = fs::remove(path, true); - if (EC && !IgnoreErrors) - return EC; - return std::error_code(); -} - std::error_code real_path(const Twine &path, SmallVectorImpl &dest, bool expand_tilde) { dest.clear(); diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index c4bd5e2472351..e70576540edaa 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -1372,32 +1372,6 @@ std::error_code closeFile(file_t &F) { return std::error_code(); } -std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { - // Convert to utf-16. - SmallVector Path16; - std::error_code EC = widenPath(path, Path16); - if (EC && !IgnoreErrors) - return EC; - - // SHFileOperation() accepts a list of paths, and so must be double null- - // terminated to indicate the end of the list. The buffer is already null - // terminated, but since that null character is not considered part of the - // vector's size, pushing another one will just consume that byte. So we - // need to push 2 null terminators. - Path16.push_back(0); - Path16.push_back(0); - - SHFILEOPSTRUCTW shfos = {}; - shfos.wFunc = FO_DELETE; - shfos.pFrom = Path16.data(); - shfos.fFlags = FOF_NO_UI; - - int result = ::SHFileOperationW(&shfos); - if (result != 0 && !IgnoreErrors) - return mapWindowsError(result); - return std::error_code(); -} - static void expandTildeExpr(SmallVectorImpl &Path) { // Path does not begin with a tilde expression. if (Path.empty() || Path[0] != '~') From a2cda5e4e815d6aaf13359689d2f8be985e6470e Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Mon, 9 Dec 2024 00:52:38 +0400 Subject: [PATCH 2/3] Reverted Unix version due to failed FileSystemTest.RealPathNoReadPerm. --- llvm/lib/Support/Path.cpp | 8 ------- llvm/lib/Support/Unix/Path.inc | 40 +++++++++++++++++++++++++++++++ llvm/lib/Support/Windows/Path.inc | 8 +++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index 4c0804f2dd494..d775285197103 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -22,7 +22,6 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include -#include #if !defined(_MSC_VER) && !defined(__MINGW32__) #include @@ -1207,13 +1206,6 @@ namespace llvm { namespace sys { namespace fs { -std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { - const std::filesystem::path Path(path.str()); - std::error_code EC; - std::filesystem::remove_all(Path, EC); - return IgnoreErrors ? std::error_code() : EC; -} - TempFile::TempFile(StringRef Name, int FD) : TmpName(std::string(Name)), FD(FD) {} TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); } diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index b8cc6b8bdb464..44097bad7b46e 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -1272,6 +1272,46 @@ std::error_code closeFile(file_t &F) { return Process::SafelyCloseFileDescriptor(TmpF); } +template +static std::error_code remove_directories_impl(const T &Entry, + bool IgnoreErrors) { + std::error_code EC; + directory_iterator Begin(Entry, EC, false); + directory_iterator End; + while (Begin != End) { + auto &Item = *Begin; + ErrorOr st = Item.status(); + if (st) { + if (is_directory(*st)) { + EC = remove_directories_impl(Item, IgnoreErrors); + if (EC && !IgnoreErrors) + return EC; + } + + EC = fs::remove(Item.path(), true); + if (EC && !IgnoreErrors) + return EC; + } else if (!IgnoreErrors) { + return st.getError(); + } + + Begin.increment(EC); + if (EC && !IgnoreErrors) + return EC; + } + return std::error_code(); +} + +std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { + auto EC = remove_directories_impl(path, IgnoreErrors); + if (EC && !IgnoreErrors) + return EC; + EC = fs::remove(path, true); + if (EC && !IgnoreErrors) + return EC; + return std::error_code(); +} + std::error_code real_path(const Twine &path, SmallVectorImpl &dest, bool expand_tilde) { dest.clear(); diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index e70576540edaa..01d01dacfd80f 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -19,6 +19,7 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/WindowsError.h" #include +#include #include #include @@ -1372,6 +1373,13 @@ std::error_code closeFile(file_t &F) { return std::error_code(); } +std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { + const std::filesystem::path Path(path.str()); + std::error_code EC; + std::filesystem::remove_all(Path, EC); + return IgnoreErrors ? std::error_code() : EC; +} + static void expandTildeExpr(SmallVectorImpl &Path) { // Path does not begin with a tilde expression. if (Path.empty() || Path[0] != '~') From 0dc400a1d9f67b1fba9e8a43997ed70da6c3eb28 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Mon, 9 Dec 2024 16:22:07 +0400 Subject: [PATCH 3/3] Reverted using widenPath(). --- llvm/lib/Support/Windows/Path.inc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 01d01dacfd80f..f433b1824adb6 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -1374,8 +1374,13 @@ std::error_code closeFile(file_t &F) { } std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { - const std::filesystem::path Path(path.str()); - std::error_code EC; + // Convert to utf-16. + SmallVector Path16; + std::error_code EC = widenPath(path, Path16); + if (EC && !IgnoreErrors) + return EC; + Path16.push_back(0); + const std::filesystem::path Path(Path16.data()); std::filesystem::remove_all(Path, EC); return IgnoreErrors ? std::error_code() : EC; }