From: Max Moroz Date: Wed, 4 Apr 2018 19:47:25 +0000 (+0000) Subject: Fixes errors with FS iterators caused by https://reviews.llvm.org/D44960 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5afe26bf33c0a2f62d9442afafe725705371f46c;p=clang Fixes errors with FS iterators caused by https://reviews.llvm.org/D44960 Summary: In https://reviews.llvm.org/D44960, file status check is executed every time a real file system directory iterator is constructed or incremented, and emits an error code. This change list fixes the errors in VirtualFileSystem caused by https://reviews.llvm.org/D44960. Patch by Yuke Liao (@liaoyuke). Reviewers: vsk, pcc, zturner, liaoyuke Reviewed By: vsk Subscribers: mgrang, cfe-commits Differential Revision: https://reviews.llvm.org/D45178 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@329223 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp index a854576959..413d43994a 100644 --- a/lib/Basic/VirtualFileSystem.cpp +++ b/lib/Basic/VirtualFileSystem.cpp @@ -286,24 +286,26 @@ class RealFSDirIter : public clang::vfs::detail::DirIterImpl { public: RealFSDirIter(const Twine &Path, std::error_code &EC) : Iter(Path, EC) { - if (!EC && Iter != llvm::sys::fs::directory_iterator()) { + if (Iter != llvm::sys::fs::directory_iterator()) { llvm::sys::fs::file_status S; - EC = llvm::sys::fs::status(Iter->path(), S, true); + std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); + if (!EC) + EC = ErrorCode; } } std::error_code increment() override { std::error_code EC; Iter.increment(EC); - if (EC) { - return EC; - } else if (Iter == llvm::sys::fs::directory_iterator()) { + if (Iter == llvm::sys::fs::directory_iterator()) { CurrentEntry = Status(); } else { llvm::sys::fs::file_status S; - EC = llvm::sys::fs::status(Iter->path(), S, true); + std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); + if (!EC) + EC = ErrorCode; } return EC; } diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp index 13c246ecc5..fe2e77668f 100644 --- a/unittests/Basic/VirtualFileSystemTest.cpp +++ b/unittests/Basic/VirtualFileSystemTest.cpp @@ -442,16 +442,17 @@ TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) { ScopedDir _dd(TestDirectory + "/d/d"); ScopedDir _ddd(TestDirectory + "/d/d/d"); ScopedLink _e("no_such_file", TestDirectory + "/e"); - std::vector Expected = {_b, _bb, _d, _dd, _ddd}; - std::vector Contents; + std::vector ExpectedBrokenSymlinks = {_a, _ba, _bc, _c, _e}; + std::vector ExpectedNonBrokenSymlinks = {_b, _bb, _d, _dd, _ddd}; + std::vector VisitedBrokenSymlinks; + std::vector VisitedNonBrokenSymlinks; std::error_code EC; for (vfs::recursive_directory_iterator I(*FS, Twine(TestDirectory), EC), E; I != E; I.increment(EC)) { - // Skip broken symlinks. auto EC2 = std::make_error_code(std::errc::no_such_file_or_directory); if (EC == EC2) { - EC.clear(); + VisitedBrokenSymlinks.push_back(I->getName()); continue; } // For bot debugging. @@ -467,13 +468,20 @@ TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) { << "EC message: " << EC2.message() << "\n"; } ASSERT_FALSE(EC); - Contents.push_back(I->getName()); + VisitedNonBrokenSymlinks.push_back(I->getName()); } - // Check sorted contents. - llvm::sort(Contents.begin(), Contents.end()); - EXPECT_EQ(Expected.size(), Contents.size()); - EXPECT_TRUE(std::equal(Contents.begin(), Contents.end(), Expected.begin())); + // Check visited file names. + std::sort(VisitedBrokenSymlinks.begin(), VisitedBrokenSymlinks.end()); + std::sort(VisitedNonBrokenSymlinks.begin(), VisitedNonBrokenSymlinks.end()); + EXPECT_EQ(ExpectedBrokenSymlinks.size(), VisitedBrokenSymlinks.size()); + EXPECT_TRUE(std::equal(VisitedBrokenSymlinks.begin(), + VisitedBrokenSymlinks.end(), + ExpectedBrokenSymlinks.begin())); + EXPECT_EQ(ExpectedNonBrokenSymlinks.size(), VisitedNonBrokenSymlinks.size()); + EXPECT_TRUE(std::equal(VisitedNonBrokenSymlinks.begin(), + VisitedNonBrokenSymlinks.end(), + ExpectedNonBrokenSymlinks.begin())); } #endif