llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Jan Svoboda (jansvoboda11)

<details>
<summary>Changes</summary>

This PR makes another piece of the `CompilerInstance::cloneForModuleCompile()` 
result thread-safe: the module build stack. This data structure is used to 
detect cyclic dependencies between modules. The problem is that it uses 
`FullSourceLoc` which refers to the `SourceManager` of the parent 
`CompilerInstance`: if two threads happen to execute `CompilerInstance`s cloned 
from the same parent concurrently, and both discover a dependency cycle, they 
may concurrently access the parent `SourceManager` when emitting the 
diagnostic, creating a data race.

In this PR, we prevent this by keeping the stack empty and moving the 
responsibility of cycle detection to the client. The client can recreate the 
same module build stack externally and ensure thread-safety by enforcing mutual 
exclusion.

---
Full diff: https://github.com/llvm/llvm-project/pull/137059.diff


1 Files Affected:

- (modified) clang/lib/Frontend/CompilerInstance.cpp (+9-5) 


``````````diff
diff --git a/clang/lib/Frontend/CompilerInstance.cpp 
b/clang/lib/Frontend/CompilerInstance.cpp
index 8596dd03148e8..1526ea53add7d 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1240,11 +1240,15 @@ std::unique_ptr<CompilerInstance> 
CompilerInstance::cloneForModuleCompileImpl(
   Instance.createSourceManager(Instance.getFileManager());
   SourceManager &SourceMgr = Instance.getSourceManager();
 
-  // Note that this module is part of the module build stack, so that we
-  // can detect cycles in the module graph.
-  SourceMgr.setModuleBuildStack(getSourceManager().getModuleBuildStack());
-  SourceMgr.pushModuleBuildStack(ModuleName,
-                                 FullSourceLoc(ImportLoc, getSourceManager()));
+  if (ThreadSafeConfig) {
+    // Detecting cycles in the module graph is responsibility of the client.
+  } else {
+    // Note that this module is part of the module build stack, so that we
+    // can detect cycles in the module graph.
+    SourceMgr.setModuleBuildStack(getSourceManager().getModuleBuildStack());
+    SourceMgr.pushModuleBuildStack(
+        ModuleName, FullSourceLoc(ImportLoc, getSourceManager()));
+  }
 
   // Make a copy for the new instance.
   Instance.FailedModules = FailedModules;

``````````

</details>


https://github.com/llvm/llvm-project/pull/137059
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to