[clang] [clang] Enable making the module build stack thread-safe (PR #137059)
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 23 13:52:39 PDT 2025
https://github.com/jansvoboda11 created https://github.com/llvm/llvm-project/pull/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.
>From 5bcb9f27d41201db8a4e7ba4c498048a50e3f7dc Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Wed, 23 Apr 2025 13:04:54 -0700
Subject: [PATCH] [clang] Enable making the module build stack thread-safe
---
clang/lib/Frontend/CompilerInstance.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
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;
More information about the cfe-commits
mailing list