Skip to content

Commit 2f849dc

Browse files
committed
[clang][cas] Treat implicit module as out-of-date if root ID is missing from CAS
If the module cache was built with a different CAS, the cas-fs-root-id will be missing and we should rebuild the module, which will ensure we have the root id in the current CAS. Note: while there is code to emit error messages it will only be exercised if we have some kind of catastrophic error after we already tried to rebuild the module - e.g. corrupted root id string, or cas removed in the middle of the compilation - so it is not tested here. (cherry picked from commit 9bf4085)
1 parent ff1155f commit 2f849dc

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

clang/include/clang/Serialization/ASTReader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ class ASTReaderListener {
239239
/// AST file imported by this AST file.
240240
virtual void visitImport(StringRef ModuleName, StringRef Filename) {}
241241

242+
/// Called for each CAS filesystem root ID.
243+
///
244+
/// \returns true to indicate \p RootID is invalid, or false otherwise.
245+
virtual bool readCASFileSystemRootID(StringRef RootID, bool Complain) {
246+
return false;
247+
}
248+
242249
/// Called for each module cache key.
243250
///
244251
/// \returns true to indicate the key cannot be loaded.
@@ -292,6 +299,7 @@ class ChainedASTReaderListener : public ASTReaderListener {
292299
serialization::ModuleKind Kind) override;
293300
bool visitInputFile(StringRef Filename, bool isSystem,
294301
bool isOverridden, bool isExplicitModule) override;
302+
bool readCASFileSystemRootID(StringRef RootID, bool Complain) override;
295303
bool readModuleCacheKey(StringRef ModuleName, StringRef Filename,
296304
StringRef CacheKey) override;
297305
void readModuleFileExtension(

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ class CompileCacheASTReaderHelper : public ASTReaderListener {
639639
DiagnosticsEngine &Diags)
640640
: CAS(CAS), Cache(Cache), ModuleCache(ModuleCache), Diags(Diags) {}
641641

642+
bool readCASFileSystemRootID(StringRef RootID, bool Complain) override;
642643
bool readModuleCacheKey(StringRef ModuleName, StringRef Filename,
643644
StringRef CacheKey) override;
644645

@@ -2426,3 +2427,22 @@ bool CompileCacheASTReaderHelper::readModuleCacheKey(StringRef ModuleName,
24262427
return addCachedModuleFileToInMemoryCache(
24272428
Filename, CacheKey, "imported module", CAS, Cache, ModuleCache, Diags);
24282429
}
2430+
2431+
bool CompileCacheASTReaderHelper::readCASFileSystemRootID(StringRef RootID,
2432+
bool Complain) {
2433+
// Verify that RootID is in the CAS. Otherwise the module cache probably was
2434+
// created with a different CAS.
2435+
std::optional<cas::CASID> ID;
2436+
if (errorToBool(CAS.parseID(RootID).moveInto(ID))) {
2437+
if (Complain)
2438+
Diags.Report(diag::err_cas_cannot_parse_root_id) << RootID;
2439+
return true;
2440+
}
2441+
if (errorToBool(CAS.getProxy(*ID).takeError())) {
2442+
if (Complain) {
2443+
Diags.Report(diag::err_cas_missing_root_id) << RootID;
2444+
}
2445+
return true;
2446+
}
2447+
return false;
2448+
}

clang/lib/Serialization/ASTReader.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
252252
isExplicitModule);
253253
return Continue;
254254
}
255+
bool ChainedASTReaderListener::readCASFileSystemRootID(StringRef RootID,
256+
bool Complain) {
257+
return First->readCASFileSystemRootID(RootID, Complain) ||
258+
Second->readCASFileSystemRootID(RootID, Complain);
259+
}
255260

256261
bool ChainedASTReaderListener::readModuleCacheKey(StringRef ModuleName,
257262
StringRef Filename,
@@ -2972,6 +2977,12 @@ ASTReader::ReadControlBlock(ModuleFile &F,
29722977

29732978
case CASFS_ROOT_ID:
29742979
F.CASFileSystemRootID = Blob.str();
2980+
if (Listener) {
2981+
bool Complain =
2982+
!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities);
2983+
if (Listener->readCASFileSystemRootID(F.CASFileSystemRootID, Complain))
2984+
return OutOfDate;
2985+
}
29752986
break;
29762987
}
29772988
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Check that the implicit modules build that the scanner performs detects
2+
// missing cas objects.
3+
4+
// REQUIRES: ondisk_cas
5+
6+
// RUN: rm -rf %t
7+
// RUN: split-file %s %t
8+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
9+
10+
// Scan to populate module cache
11+
12+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
13+
// RUN: -cas-path %t/cas -action-cache-path %t/cache -module-files-dir %t/outputs \
14+
// RUN: -format experimental-full -mode preprocess-dependency-directives
15+
16+
// Clear cas and re-scan
17+
18+
// RUN: rm -rf %t/cas
19+
20+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
21+
// RUN: -cas-path %t/cas -action-cache-path %t/cache -module-files-dir %t/outputs \
22+
// RUN: -format experimental-full -mode preprocess-dependency-directives \
23+
// RUN: > %t/deps.json
24+
25+
// Build module and TU
26+
27+
// RUN: %deps-to-rsp %t/deps.json --module-name Mod > %t/Mod.rsp
28+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
29+
// RUN: %clang @%t/Mod.rsp
30+
// RUN: %clang @%t/tu.rsp
31+
32+
//--- cdb.json.template
33+
[{
34+
"directory" : "DIR",
35+
"command" : "clang_tool -fsyntax-only DIR/tu.c -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache",
36+
"file" : "DIR/tu.c"
37+
}]
38+
39+
//--- module.modulemap
40+
module Mod { header "Mod.h" }
41+
42+
//--- Mod.h
43+
void mod(void);
44+
45+
//--- tu.c
46+
#include "Mod.h"
47+
void tu(void) {
48+
mod();
49+
}

0 commit comments

Comments
 (0)