Skip to content

Commit 8832a59

Browse files
authored
[clang] Enable making the module build stack thread-safe (llvm#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.
1 parent 7a276c8 commit 8832a59

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,11 +1240,15 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
12401240
Instance.createSourceManager(Instance.getFileManager());
12411241
SourceManager &SourceMgr = Instance.getSourceManager();
12421242

1243-
// Note that this module is part of the module build stack, so that we
1244-
// can detect cycles in the module graph.
1245-
SourceMgr.setModuleBuildStack(getSourceManager().getModuleBuildStack());
1246-
SourceMgr.pushModuleBuildStack(ModuleName,
1247-
FullSourceLoc(ImportLoc, getSourceManager()));
1243+
if (ThreadSafeConfig) {
1244+
// Detecting cycles in the module graph is responsibility of the client.
1245+
} else {
1246+
// Note that this module is part of the module build stack, so that we
1247+
// can detect cycles in the module graph.
1248+
SourceMgr.setModuleBuildStack(getSourceManager().getModuleBuildStack());
1249+
SourceMgr.pushModuleBuildStack(
1250+
ModuleName, FullSourceLoc(ImportLoc, getSourceManager()));
1251+
}
12481252

12491253
// Make a copy for the new instance.
12501254
Instance.FailedModules = FailedModules;

0 commit comments

Comments
 (0)