[llvm] [DWARFLinker] Skip module registration with --update (PR #219535)

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 10:12:17 PDT 2026


https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/219535

Update mode regenerates accelerator tables without linking DWARF, so addObjectFile() skips registerModuleReference() and never resolves clang module references. It also keeps module skeleton units in the compile unit list, which the non-update path would have filtered out.

This breaks the assumption that the second time registerModuleReference is called, it does no new work and is thread safe.

Guard it the same way addObjectFile() and the classic linker do, restoring the no-op assumption the comment describes and fixing the data race.

>From f9bfb893f356f0a42dff465d3177941d275503a3 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Fri, 28 Aug 2026 10:07:23 -0700
Subject: [PATCH] [DWARFLinker] Skip module registration with --update

Update mode regenerates accelerator tables without linking DWARF, so
addObjectFile() skips registerModuleReference() and never resolves clang
module references. It also keeps module skeleton units in the compile
unit list, which the non-update path would have filtered out.

This breaks the assumption that the second time registerModuleReference
is called, it does no new work and is thread safe.

Guard it the same way addObjectFile() and the classic linker do,
restoring the no-op assumption the comment describes and fixing the data
race.
---
 llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp |  7 ++++++-
 llvm/test/tools/dsymutil/X86/update-modules.test  | 15 +++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/tools/dsymutil/X86/update-modules.test

diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
index 0999e58ef1a5d..f8cae89391d71 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
@@ -652,7 +652,12 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
             // registerModuleReferences doesn't do any new work, but it
             // will collect top-level errors, which are suppressed. Module
             // warnings were already displayed in the first iteration.
-            if (registerModuleReference(
+            //
+            // Runs concurrently, so it must stay a no-op: it may only be
+            // entered when the serial pass in addObjectFile() has already
+            // populated the module map.
+            if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
+                registerModuleReference(
                     CU.getOrigUnit().getUnitDIE(), nullptr,
                     [](const DWARFUnit &) {}, 0))
               CU.setStage(CompileUnit::Stage::PatchesUpdated);
diff --git a/llvm/test/tools/dsymutil/X86/update-modules.test b/llvm/test/tools/dsymutil/X86/update-modules.test
new file mode 100644
index 0000000000000..e8ab23b717759
--- /dev/null
+++ b/llvm/test/tools/dsymutil/X86/update-modules.test
@@ -0,0 +1,15 @@
+Update mode regenerates accelerator tables without linking DWARF, so clang module
+references are left unresolved. The parallel linker must not try to load the
+referenced .pcm files.
+
+RUN: dsymutil --update --linker parallel -oso-prepend-path=%p/../Inputs/modules \
+RUN:   -y %p/dummy-debug-map.map -o %t.parallel.dSYM 2>&1 \
+RUN:   | FileCheck %s --implicit-check-not="clang module"
+
+RUN: dsymutil --update --linker classic -oso-prepend-path=%p/../Inputs/modules \
+RUN:   -y %p/dummy-debug-map.map -o %t.classic.dSYM 2>&1 \
+RUN:   | FileCheck %s --implicit-check-not="clang module"
+
+The debug map names objects that are not part of this input directory.
+
+CHECK: warning: {{.*}}3.o



More information about the llvm-commits mailing list