Skip to content

Commit f76a3c5

Browse files
committed
[clang][cas] Fix error accessing cached failure for dep directive scan
When we fail to scan directives in a file we store an empty blob to cache the failure, but we didn't correctly handle it when loading that empty blob from the cache. This was triggering crashes the second time we try to scan a script file. Note: failure to scan is correct here; it's not C++ code but we had no way to know that up front. rdar://106090616 (cherry picked from commit 8fb4d9a)
1 parent 52808bd commit f76a3c5

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

clang/lib/Tooling/DependencyScanning/DependencyScanningCASFilesystem.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ void DependencyScanningCASFilesystem::scanForDirectives(
165165
if (Optional<CASID> OutputID =
166166
reportAsFatalIfError(Cache.get(*InputID))) {
167167
if (Optional<ObjectRef> OutputRef = CAS.getReference(*OutputID)) {
168+
if (OutputRef == EmptyBlobID)
169+
return; // Cached directive scanning failure.
168170
reportAsFatalIfError(
169171
loadDepDirectives(CAS, *OutputRef, Tokens, Directives));
170172
return;

clang/unittests/Tooling/DependencyScanningCASFilesystemTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,25 @@ TEST(DependencyScanningCASFilesystem, FilenameSpelling) {
4242
ASSERT_TRUE(DirectivesSymlink);
4343
EXPECT_EQ(DirectivesSymlink->size(), 2u);
4444
}
45+
46+
TEST(DependencyScanningCASFilesystem, DirectiveScanFailure) {
47+
TempDir TestDir("DependencyScanningCASFilesystemTest", /*Unique=*/true);
48+
TempFile TestFile(TestDir.path("python"), "", "import sys\n");
49+
50+
std::unique_ptr<ObjectStore> CAS = llvm::cas::createInMemoryCAS();
51+
std::unique_ptr<ActionCache> Cache = llvm::cas::createInMemoryActionCache();
52+
auto CacheFS = llvm::cantFail(llvm::cas::createCachingOnDiskFileSystem(*CAS));
53+
DependencyScanningCASFilesystem FS(CacheFS, *Cache);
54+
55+
EXPECT_EQ(FS.status(TestFile.path()).getError(), std::error_code());
56+
auto Directives = FS.getDirectiveTokens(TestFile.path());
57+
ASSERT_FALSE(Directives);
58+
59+
// Check the cached failure in the action cache.
60+
{
61+
DependencyScanningCASFilesystem NewFS(CacheFS, *Cache);
62+
EXPECT_EQ(NewFS.status(TestFile.path()).getError(), std::error_code());
63+
auto Directives = NewFS.getDirectiveTokens(TestFile.path());
64+
ASSERT_FALSE(Directives);
65+
}
66+
}

0 commit comments

Comments
 (0)