[clang] [PATCH] [clang][modules] Fix serialization and de-serialization of PCH module file refs (#105994) (PR #132802)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 24 11:27:03 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Paul Schwabauer (koplas)
<details>
<summary>Changes</summary>
The File ID is incorrectly calculated, resulting in an out-of-bounds access. The test code is more complex because the File fetching only happens in specific scenarios.
---
Full diff: https://github.com/llvm/llvm-project/pull/132802.diff
2 Files Affected:
- (modified) clang/lib/Serialization/ASTReader.cpp (+2-2)
- (added) clang/test/Modules/MixedModulePrecompile.cpp (+49)
``````````diff
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 2728e93c69516..7540ff5a3a95c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9615,7 +9615,7 @@ ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) const {
// It's a prefix (preamble, PCH, ...). Look it up by index.
unsigned IndexFromEnd = ID >> 1;
assert(IndexFromEnd && "got reference to unknown module file");
- return getModuleManager().pch_modules().end()[-IndexFromEnd];
+ return getModuleManager().pch_modules().end()[-static_cast<int>(IndexFromEnd)];
}
}
@@ -9633,7 +9633,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *M) {
auto PCHModules = getModuleManager().pch_modules();
auto I = llvm::find(PCHModules, M);
assert(I != PCHModules.end() && "emitting reference to unknown file");
- return (I - PCHModules.end()) << 1;
+ return std::distance(I, PCHModules.end()) << 1;
}
std::optional<ASTSourceDescriptor> ASTReader::getSourceDescriptor(unsigned ID) {
diff --git a/clang/test/Modules/MixedModulePrecompile.cpp b/clang/test/Modules/MixedModulePrecompile.cpp
new file mode 100644
index 0000000000000..a800498cd2670
--- /dev/null
+++ b/clang/test/Modules/MixedModulePrecompile.cpp
@@ -0,0 +1,49 @@
+// Tests mixed usage of precompiled headers and modules.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -x c++-header -emit-pch %t/a.hpp \
+// RUN: -o %t/a.pch
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part1.cppm \
+// RUN: -include-pch %t/a.pch -o %t/Part1.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part2.cppm \
+// RUN: -include-pch %t/a.pch -o %t/Part2.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part3.cppm \
+// RUN: -include-pch %t/a.pch -o %t/Part3.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part4.cppm \
+// RUN: -include-pch %t/a.pch -o %t/Part4.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface -fprebuilt-module-path=%t -fprebuilt-implicit-modules %t/Mod.cppm \
+// RUN: -include-pch %t/a.pch -o %t/Mod.pcm
+
+
+//--- a.hpp
+#pragma once
+
+class a {
+ virtual ~a();
+ a() {}
+};
+
+//--- Part1.cppm
+export module mod:part1;
+
+//--- Part2.cppm
+export module mod:part2;
+
+//--- Part3.cppm
+export module mod:part3;
+
+//--- Part4.cppm
+export module mod:part4;
+
+//--- Mod.cppm
+export module mod;
+export import :part1;
+export import :part2;
+export import :part3;
+export import :part4;
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/132802
More information about the cfe-commits
mailing list