Skip to content

[clang][modulemap] Fix crashes loading pcms - #218011

Merged
keith merged 1 commit into
llvm:mainfrom
keith:ks/clang-modulemap-fix-crashes-loading-pcms
Aug 27, 2026
Merged

keith merged 1 commit into
llvm:mainfrom
keith:ks/clang-modulemap-fix-crashes-loading-pcms

Conversation

@keith

@keith keith commented Aug 21, 2026

Copy link
Copy Markdown
Member

Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to #181916

Fixes: #215931

Assisted By: codex

Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to llvm#181916

Fixes: llvm#215931

Assisted By: codex
@llvmorg-github-actions llvmorg-github-actions Bot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules labels Aug 21, 2026
@keith

keith commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

@Bigcheese @jansvoboda11 from the related change

@llvmorg-github-actions

llvmorg-github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-modules

Author: Keith Smiley (keith)

Changes

Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to #181916

Fixes: #215931

Assisted By: codex


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

2 Files Affected:

  • (modified) clang/lib/Lex/ModuleMap.cpp (+12-10)
  • (added) clang/test/Modules/pr215931.m (+38)
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 6c07386f89010..9e0202409dfb2 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -175,10 +175,6 @@ static void appendSubframeworkPaths(Module *Mod,
 OptionalFileEntryRef ModuleMap::findHeader(
     Module *M, const Module::UnresolvedHeaderDirective &Header,
     SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
-  // Search for the header file within the module's home directory.
-  auto Directory = M->Directory;
-  SmallString<128> FullPathName(Directory->getName());
-
   auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
     auto File = SourceMgr.getFileManager().getOptionalFileRef(Filename);
     if (!File || (Header.Size && File->getSize() != *Header.Size) ||
@@ -187,6 +183,18 @@ OptionalFileEntryRef ModuleMap::findHeader(
     return *File;
   };
 
+  if (llvm::sys::path::is_absolute(Header.FileName)) {
+    RelativePathName.clear();
+    RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
+    return GetFile(Header.FileName);
+  }
+
+  // Search for the header file within the module's home directory.
+  auto Directory = M->Directory;
+  if (!Directory)
+    return std::nullopt;
+  SmallString<128> FullPathName(Directory->getName());
+
   auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {
     unsigned FullPathLength = FullPathName.size();
     appendSubframeworkPaths(M, RelativePathName);
@@ -215,12 +223,6 @@ OptionalFileEntryRef ModuleMap::findHeader(
     return GetFile(FullPathName);
   };
 
-  if (llvm::sys::path::is_absolute(Header.FileName)) {
-    RelativePathName.clear();
-    RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
-    return GetFile(Header.FileName);
-  }
-
   if (M->isPartOfFramework())
     return GetFrameworkFile();
 
diff --git a/clang/test/Modules/pr215931.m b/clang/test/Modules/pr215931.m
new file mode 100644
index 0000000000000..7a8a5476e4a9a
--- /dev/null
+++ b/clang/test/Modules/pr215931.m
@@ -0,0 +1,38 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// A PCM whose paths are relative to the consumer's working directory should
+// load successfully even though it does not contain a MODULE_DIRECTORY record.
+// RUN: %clang_cc1 -emit-module -x objective-c -fmodules \
+// RUN:   -fno-implicit-modules -fmodule-file-home-is-cwd \
+// RUN:   -fmodule-name=Repro mod/module.modulemap -o Repro-relative.pcm
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fmodules \
+// RUN:   -fno-implicit-modules -fmodule-file-home-is-cwd \
+// RUN:   -fmodule-file=Repro=Repro-relative.pcm use.m
+
+// An explicitly loaded PCM should also not crash if its absolute module home
+// directory has been removed.
+// RUN: %clang_cc1 -emit-module -x objective-c -fmodules \
+// RUN:   -fno-implicit-modules -fmodule-name=Repro \
+// RUN:   mod/module.modulemap -o Repro-absolute.pcm
+// RUN: rm -rf mod
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fmodules \
+// RUN:   -fno-implicit-modules -fmodule-file=Repro=Repro-absolute.pcm use.m
+
+//--- mod/module.modulemap
+module Repro {
+  umbrella header "Repro.h"
+  export *
+  module * { export * }
+}
+
+//--- mod/Repro.h
+#include "sub.h"
+
+//--- mod/sub.h
+static inline int repro_answer(void) { return 42; }
+
+//--- use.m
+@import Repro;
+int main(void) { return repro_answer(); }

@keith

keith commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

bump

@Bigcheese Bigcheese left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Thanks for fixing this!

@keith
keith merged commit cd1abef into llvm:main Aug 27, 2026
16 checks passed
@keith
keith deleted the ks/clang-modulemap-fix-crashes-loading-pcms branch August 27, 2026 23:42
wlemkows pushed a commit to wlemkows/llvm-project that referenced this pull request Sep 4, 2026
Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to llvm#181916

Fixes: llvm#215931

Assisted By: codex
asudarsa-qti pushed a commit to asudarsa-qti/llvm-project that referenced this pull request Sep 4, 2026
Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to llvm#181916

Fixes: llvm#215931

Assisted By: codex
cyndyishida pushed a commit to swiftlang/llvm-project that referenced this pull request Sep 9, 2026
Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to llvm#181916

Fixes: llvm#215931

Assisted By: codex

(cherry picked from commit cd1abef)
@Bigcheese

Copy link
Copy Markdown
Contributor

/cherry-pick cd1abef

@llvmbot

llvmbot commented Sep 16, 2026

Copy link
Copy Markdown
Member

/cherry-pick cd1abef

Error: Command failed due to missing milestone.

@Bigcheese

Copy link
Copy Markdown
Contributor

/cherry-pick cd1abef

@keith

keith commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

thanks, i'm happy to help shepard as needed too, i should have submitted this earlier!

@llvmbot

llvmbot commented Sep 16, 2026

Copy link
Copy Markdown
Member

/pull-request #224159

dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Sep 18, 2026
Previously in the case that the directory was missing, loading a pcm
would crash. Now it attempts to load absolute paths first, and
gracefully ignores missing directories.

Follow up to llvm#181916

Fixes: llvm#215931

Assisted By: codex

(cherry picked from commit cd1abef)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

Development

Successfully merging this pull request may close these issues.

[clang] ASTReader crashes in ModuleMap::findHeader loading a PCM with an umbrella header (23.1.0-rc regression)

3 participants