]> granicus.if.org Git - clang/commitdiff
[Tooling] Avoid working-dir races in AllTUsToolExecutor
authorIlya Biryukov <ibiryukov@google.com>
Fri, 22 Mar 2019 11:01:13 +0000 (11:01 +0000)
committerIlya Biryukov <ibiryukov@google.com>
Fri, 22 Mar 2019 11:01:13 +0000 (11:01 +0000)
Reviewers: ioeric

Reviewed By: ioeric

Subscribers: jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59683

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356743 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Tooling/AllTUsExecution.cpp

index bc50412cf4fabd5c9d978bccdc66ec4571195a3a..ca9db7a561beda64780e5ef7ddf073e2ee1d695a 100644 (file)
@@ -9,6 +9,7 @@
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 namespace clang {
 namespace tooling {
@@ -114,25 +115,22 @@ llvm::Error AllTUsToolExecutor::execute(
   {
     llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
                                            : ThreadCount);
-    llvm::SmallString<128> InitialWorkingDir;
-    if (auto EC = llvm::sys::fs::current_path(InitialWorkingDir)) {
-      InitialWorkingDir = "";
-      llvm::errs() << "Error while getting current working directory: "
-                   << EC.message() << "\n";
-    }
     for (std::string File : Files) {
       Pool.async(
           [&](std::string Path) {
             Log("[" + std::to_string(Count()) + "/" + TotalNumStr +
                 "] Processing file " + Path);
-            ClangTool Tool(Compilations, {Path});
+            // Each thread gets an indepent copy of a VFS to allow different
+            // concurrent working directories.
+            IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
+                llvm::vfs::createPhysicalFileSystem().release();
+            ClangTool Tool(Compilations, {Path},
+                           std::make_shared<PCHContainerOperations>(), FS);
             Tool.appendArgumentsAdjuster(Action.second);
             Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
             for (const auto &FileAndContent : OverlayFiles)
               Tool.mapVirtualFile(FileAndContent.first(),
                                   FileAndContent.second);
-            // Do not restore working dir from multiple threads to avoid races.
-            Tool.setRestoreWorkingDir(false);
             if (Tool.run(Action.first.get()))
               AppendError(llvm::Twine("Failed to run action on ") + Path +
                           "\n");
@@ -141,11 +139,6 @@ llvm::Error AllTUsToolExecutor::execute(
     }
     // Make sure all tasks have finished before resetting the working directory.
     Pool.wait();
-    if (!InitialWorkingDir.empty()) {
-      if (auto EC = llvm::sys::fs::set_current_path(InitialWorkingDir))
-        llvm::errs() << "Error while restoring working directory: "
-                     << EC.message() << "\n";
-    }
   }
 
   if (!ErrorMsg.empty())