Skip to content

Commit ac42b08

Browse files
authored
[clang][modules] Guard against bad -fmodule-file mappings (llvm#132059) (llvm#133462)
Fix llvm#132059. Providing incorrect mappings via `-fmodule-file=<name>=<path/to/bmi>` can crash the compiler when loading a module that imports an incorrectly mapped module. The crash occurs during AST body deserialization, when the compiler attempts to resolve remappings using the `ModuleFile` from the incorrectly mapped module's BMI file. The cause is an invalid access into an incorrectly loaded `ModuleFile`. This commit fixes the issue by verifying the identity of the imported module.
1 parent f1bb2fe commit ac42b08

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

clang/lib/Serialization/ASTReader.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,6 +3318,18 @@ ASTReader::ReadControlBlock(ModuleFile &F,
33183318
Loaded, StoredSize, StoredModTime,
33193319
StoredSignature, Capabilities);
33203320

3321+
// Check the AST we just read from ImportedFile contains a different
3322+
// module than we expected (ImportedName). This can occur for C++20
3323+
// Modules when given a mismatch via -fmodule-file=<name>=<file>
3324+
if (IsImportingStdCXXModule) {
3325+
if (const auto *Imported =
3326+
getModuleManager().lookupByFileName(ImportedFile);
3327+
Imported != nullptr && Imported->ModuleName != ImportedName) {
3328+
Diag(diag::err_failed_to_find_module_file) << ImportedName;
3329+
Result = Missing;
3330+
}
3331+
}
3332+
33213333
// If we diagnosed a problem, produce a backtrace.
33223334
bool recompilingFinalized = Result == OutOfDate &&
33233335
(Capabilities & ARR_OutOfDate) &&
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: cd %t
4+
5+
// Related to issue #132059
6+
7+
// Precompile the module dependencies correctly
8+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface a.cppm -o a.pcm
9+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface b.cppm -o b.pcm \
10+
// RUN: -fmodule-file=A=a.pcm
11+
12+
// Verify that providing incorrect mappings via
13+
// `-fmodule-file=<name>=<path/to/bmi>` does not crash the compiler when loading
14+
// a module that imports the incorrectly mapped module.
15+
// RUN: not %clang_cc1 -std=c++20 main1.cpp -fmodule-file=A=b.pcm
16+
17+
//--- a.cppm
18+
export module A;
19+
20+
export int a() {
21+
return 41;
22+
}
23+
24+
//--- b.cppm
25+
export module B;
26+
import A;
27+
28+
export int b() {
29+
return a() + 1;
30+
}
31+
32+
//--- main1.cpp
33+
import A;
34+
35+
int main() {
36+
return a();
37+
}
38+
39+
// Test again for the case where the BMI is first loaded correctly
40+
// RUN: not %clang_cc1 -std=c++20 main2.cpp-fmodule-file=B=b.pcm \
41+
// RUN: -fmodule-file=A=b.pcm
42+
43+
//--- main2.cpp
44+
import B;
45+
46+
int main() {
47+
return b();
48+
}

0 commit comments

Comments
 (0)