Skip to content

Commit e740675

Browse files
koplaststellar
authored andcommitted
[PATCH] [clang][modules] Fix serialization and de-serialization of PCH module file refs (llvm#105994) (llvm#132802)
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. --------- Co-authored-by: ShaderKeeper <[email protected]> Co-authored-by: Chuanqi Xu <[email protected]> (cherry picked from commit cca0f81)
1 parent 2f6c580 commit e740675

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

clang/lib/Serialization/ASTReader.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -9616,9 +9616,9 @@ ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) const {
96169616
return I == GlobalSubmoduleMap.end() ? nullptr : I->second;
96179617
} else {
96189618
// It's a prefix (preamble, PCH, ...). Look it up by index.
9619-
unsigned IndexFromEnd = ID >> 1;
9619+
int IndexFromEnd = static_cast<int>(ID >> 1);
96209620
assert(IndexFromEnd && "got reference to unknown module file");
9621-
return getModuleManager().pch_modules().end()[-IndexFromEnd];
9621+
return getModuleManager().pch_modules().end()[-static_cast<int>(IndexFromEnd)];
96229622
}
96239623
}
96249624

@@ -9636,7 +9636,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *M) {
96369636
auto PCHModules = getModuleManager().pch_modules();
96379637
auto I = llvm::find(PCHModules, M);
96389638
assert(I != PCHModules.end() && "emitting reference to unknown file");
9639-
return (I - PCHModules.end()) << 1;
9639+
return std::distance(I, PCHModules.end()) << 1;
96409640
}
96419641

96429642
std::optional<ASTSourceDescriptor> ASTReader::getSourceDescriptor(unsigned ID) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Tests mixed usage of precompiled headers and modules.
2+
//
3+
// RUN: rm -rf %t
4+
// RUN: mkdir -p %t
5+
// RUN: split-file %s %t
6+
//
7+
// RUN: %clang_cc1 -std=c++20 -x c++-header -emit-pch %t/a.hpp \
8+
// RUN: -o %t/a.pch
9+
10+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part1.cppm \
11+
// RUN: -include-pch %t/a.pch -o %t/Part1.pcm
12+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part2.cppm \
13+
// RUN: -include-pch %t/a.pch -o %t/Part2.pcm
14+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part3.cppm \
15+
// RUN: -include-pch %t/a.pch -o %t/Part3.pcm
16+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Part4.cppm \
17+
// RUN: -include-pch %t/a.pch -o %t/Part4.pcm
18+
19+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface \
20+
// RUN: -fmodule-file=mod:part1=%t/Part1.pcm \
21+
// RUN: -fmodule-file=mod:part2=%t/Part2.pcm \
22+
// RUN: -fmodule-file=mod:part3=%t/Part3.pcm \
23+
// RUN: -fmodule-file=mod:part4=%t/Part4.pcm \
24+
// RUN: %t/Mod.cppm \
25+
// RUN: -include-pch %t/a.pch -o %t/Mod.pcm
26+
27+
// RUN: %clang_cc1 -std=c++20 -emit-obj \
28+
// RUN: -main-file-name Mod.cppm \
29+
// RUN: -fmodule-file=mod:part1=%t/Part1.pcm \
30+
// RUN: -fmodule-file=mod:part2=%t/Part2.pcm \
31+
// RUN: -fmodule-file=mod:part3=%t/Part3.pcm \
32+
// RUN: -fmodule-file=mod:part4=%t/Part4.pcm \
33+
// RUN: -x pcm %t/Mod.pcm \
34+
// RUN: -include-pch %t/a.pch -o %t/Mod.o
35+
36+
37+
//--- a.hpp
38+
#pragma once
39+
40+
class a {
41+
virtual ~a();
42+
a() {}
43+
};
44+
45+
//--- Part1.cppm
46+
export module mod:part1;
47+
48+
//--- Part2.cppm
49+
export module mod:part2;
50+
51+
//--- Part3.cppm
52+
export module mod:part3;
53+
54+
//--- Part4.cppm
55+
export module mod:part4;
56+
57+
//--- Mod.cppm
58+
export module mod;
59+
export import :part1;
60+
export import :part2;
61+
export import :part3;
62+
export import :part4;
63+

0 commit comments

Comments
 (0)