diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -1273,19 +1273,20 @@ while (Begin != End) { auto &Item = *Begin; ErrorOr st = Item.status(); - if (!st && !IgnoreErrors) - return st.getError(); + if (st) { + if (is_directory(*st)) { + EC = remove_directories_impl(Item, IgnoreErrors); + if (EC && !IgnoreErrors) + return EC; + } - if (is_directory(*st)) { - EC = remove_directories_impl(Item, IgnoreErrors); + EC = fs::remove(Item.path(), true); if (EC && !IgnoreErrors) return EC; + } else if (!IgnoreErrors) { + return st.getError(); } - EC = fs::remove(Item.path(), true); - if (EC && !IgnoreErrors) - return EC; - Begin.increment(EC); if (EC && !IgnoreErrors) return EC; diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -816,6 +816,28 @@ ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noreadperm")); } +TEST_F(FileSystemTest, RemoveDirectoriesNoExePerm) { + SmallString<64> Expanded; + + ASSERT_NO_ERROR( + fs::create_directories(Twine(TestDirectory) + "/noexeperm/foo")); + ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/noexeperm/foo")); + + fs::setPermissions(Twine(TestDirectory) + "/noexeperm", + fs::all_read | fs::all_write); + + ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noexeperm", + /*IgnoreErrors=*/true)); + ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/noexeperm")); + ASSERT_EQ(fs::remove_directories(Twine(TestDirectory) + "/noexeperm", + /*IgnoreErrors=*/false), + errc::permission_denied); + + fs::setPermissions(Twine(TestDirectory) + "/noexeperm", fs::all_perms); + + ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noexeperm", + /*IgnoreErrors=*/false)); +} #endif