diff options
author | Jan Svoboda <jan_svoboda@apple.com> | 2025-04-24 10:18:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-24 10:18:45 -0700 |
commit | 8832a5950f3b62331842ecb2f3a68f33732822eb (patch) | |
tree | 3e4326e877e53faf5cf47f058e64f9c8c321b944 /clang/lib/Frontend/CompilerInstance.cpp | |
parent | 7a276c8acfc3977de8c3ceb0af67fcf603834946 (diff) | |
download | llvm-8832a5950f3b62331842ecb2f3a68f33732822eb.zip llvm-8832a5950f3b62331842ecb2f3a68f33732822eb.tar.gz llvm-8832a5950f3b62331842ecb2f3a68f33732822eb.tar.bz2 |
[clang] Enable making the module build stack thread-safe (#137059)
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.
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 8596dd0..1526ea5 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; |