Skip to content

Commit f65b0b5

Browse files
committed
Revert "[VFS] RedirectingFileSystem only replace path if not already mapped"
This reverts commit 3fda0ed, which breaks crash reproducers in very specific circumstances. Specifically, since crash reproducers have `UseExternalNames` set to false, the `File->getFileEntry().getDir()->getName()` call in `DoFrameworkLookup` would use the *cached* directory name instead of the directory of the looked-up file. The plan is to re-commit this patch but to *add* `ExposesExternalVFSPath` rather than replace `IsVFSMapped`. Differential Revision: https://reviews.llvm.org/D123103
1 parent c2f6460 commit f65b0b5

File tree

5 files changed

+38
-104
lines changed

5 files changed

+38
-104
lines changed

clang/lib/Basic/FileManager.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,12 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
274274
if (!UFE)
275275
UFE = new (FilesAlloc.Allocate()) FileEntry();
276276

277-
// FIXME: This should just check `!Status.ExposesExternalVFSPath`, but the
278-
// else branch also ends up fixing up relative paths to be the actually
279-
// looked up absolute path. This isn't necessarily desired, but does seem to
280-
// be relied on in some clients.
281277
if (Status.getName() == Filename) {
282278
// The name matches. Set the FileEntry.
283279
NamedFileEnt->second = FileEntryRef::MapValue(*UFE, DirInfo);
284280
} else {
285-
// We need a redirect. First grab the actual entry we want to return.
281+
// Name mismatch. We need a redirect. First grab the actual entry we want
282+
// to return.
286283
//
287284
// This redirection logic intentionally leaks the external name of a
288285
// redirected file that uses 'use-external-name' in \a
@@ -292,11 +289,9 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
292289
//
293290
// FIXME: This is pretty complicated. It's also inconsistent with how
294291
// "real" filesystems behave and confuses parts of clang expect to see the
295-
// name-as-accessed on the \a FileEntryRef. To remove this we should
296-
// implement the FIXME on `ExposesExternalVFSPath`, ie. update the
297-
// `FileEntryRef::getName()` path to *always* be the virtual path and have
298-
// clients request the external path only when required through a separate
299-
// API.
292+
// name-as-accessed on the \a FileEntryRef. Maybe the returned \a
293+
// FileEntryRef::getName() could return the accessed name unmodified, but
294+
// make the external name available via a separate API.
300295
auto &Redirection =
301296
*SeenFileEntries
302297
.insert({Status.getName(), FileEntryRef::MapValue(*UFE, DirInfo)})
@@ -317,16 +312,13 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
317312
FileEntryRef ReturnedRef(*NamedFileEnt);
318313
if (ReusingEntry) { // Already have an entry with this inode, return it.
319314

320-
// FIXME: This hack ensures that `getDir()` will use the path that was
321-
// used to lookup this file, even if we found a file by different path
322-
// first. This is required in order to find a module's structure when its
323-
// headers/module map are mapped in the VFS.
324-
//
325-
// This should be removed once `HeaderSearch` is updated to use `*Ref`s
326-
// *and* the redirection hack above is removed. The removal of the latter
327-
// is required since otherwise the ref will have the exposed external VFS
328-
// path still.
329-
if (&DirInfo.getDirEntry() != UFE->Dir && Status.ExposesExternalVFSPath)
315+
// FIXME: this hack ensures that if we look up a file by a virtual path in
316+
// the VFS that the getDir() will have the virtual path, even if we found
317+
// the file by a 'real' path first. This is required in order to find a
318+
// module's structure when its headers/module map are mapped in the VFS.
319+
// We should remove this as soon as we can properly support a file having
320+
// multiple names.
321+
if (&DirInfo.getDirEntry() != UFE->Dir && Status.IsVFSMapped)
330322
UFE->Dir = &DirInfo.getDirEntry();
331323

332324
// Always update LastRef to the last name by which a file was accessed.

clang/test/VFS/external-names-multi-overlay.c

Lines changed: 0 additions & 39 deletions
This file was deleted.

llvm/include/llvm/Support/VirtualFileSystem.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,8 @@ class Status {
5555
llvm::sys::fs::perms Perms;
5656

5757
public:
58-
/// Whether this entity has an external path different from the virtual path,
59-
/// and the external path is exposed by leaking it through the abstraction.
60-
/// For example, a RedirectingFileSystem will set this for paths where
61-
/// UseExternalName is true.
62-
///
63-
/// FIXME: Currently the external path is exposed by replacing the virtual
64-
/// path in this Status object. Instead, we should leave the path in the
65-
/// Status intact (matching the requested virtual path), and just use this
66-
/// flag as hint that a new API, FileSystem::getExternalVFSPath(), will not
67-
/// return `None`. Clients can then request the external path only where
68-
/// needed (e.g. for diagnostics, or to report discovered dependencies to
69-
/// external tools).
70-
bool ExposesExternalVFSPath = false;
58+
// FIXME: remove when files support multiple names
59+
bool IsVFSMapped = false;
7160

7261
Status() = default;
7362
Status(const llvm::sys::fs::file_status &Status);

llvm/lib/Support/VirtualFileSystem.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,16 +2163,10 @@ RedirectingFileSystem::lookupPathImpl(
21632163
static Status getRedirectedFileStatus(const Twine &OriginalPath,
21642164
bool UseExternalNames,
21652165
Status ExternalStatus) {
2166-
// The path has been mapped by some nested VFS, don't override it with the
2167-
// original path.
2168-
if (ExternalStatus.ExposesExternalVFSPath)
2169-
return ExternalStatus;
2170-
21712166
Status S = ExternalStatus;
21722167
if (!UseExternalNames)
21732168
S = Status::copyWithNewName(S, OriginalPath);
2174-
else
2175-
S.ExposesExternalVFSPath = true;
2169+
S.IsVFSMapped = true;
21762170
return S;
21772171
}
21782172

@@ -2274,9 +2268,7 @@ class FileWithFixedStatus : public File {
22742268

22752269
ErrorOr<std::unique_ptr<File>>
22762270
File::getWithPath(ErrorOr<std::unique_ptr<File>> Result, const Twine &P) {
2277-
// See \c getRedirectedFileStatus - don't update path if it's already been
2278-
// mapped.
2279-
if (!Result || (*Result)->status()->ExposesExternalVFSPath)
2271+
if (!Result)
22802272
return Result;
22812273

22822274
ErrorOr<std::unique_ptr<File>> F = std::move(*Result);

llvm/unittests/Support/VirtualFileSystemTest.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,20 +1442,20 @@ TEST_F(VFSFromYAMLTest, MappedFiles) {
14421442
ErrorOr<vfs::Status> S = O->status("//root/file1");
14431443
ASSERT_FALSE(S.getError());
14441444
EXPECT_EQ("//root/foo/bar/a", S->getName());
1445-
EXPECT_TRUE(S->ExposesExternalVFSPath);
1445+
EXPECT_TRUE(S->IsVFSMapped);
14461446

14471447
ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
14481448
EXPECT_EQ("//root/foo/bar/a", SLower->getName());
14491449
EXPECT_TRUE(S->equivalent(*SLower));
1450-
EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1450+
EXPECT_FALSE(SLower->IsVFSMapped);
14511451

14521452
// file after opening
14531453
auto OpenedF = O->openFileForRead("//root/file1");
14541454
ASSERT_FALSE(OpenedF.getError());
14551455
auto OpenedS = (*OpenedF)->status();
14561456
ASSERT_FALSE(OpenedS.getError());
14571457
EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1458-
EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1458+
EXPECT_TRUE(OpenedS->IsVFSMapped);
14591459

14601460
// directory
14611461
S = O->status("//root/");
@@ -1467,43 +1467,43 @@ TEST_F(VFSFromYAMLTest, MappedFiles) {
14671467
S = O->status("//root/mappeddir");
14681468
ASSERT_FALSE(S.getError());
14691469
EXPECT_TRUE(S->isDirectory());
1470-
EXPECT_TRUE(S->ExposesExternalVFSPath);
1470+
EXPECT_TRUE(S->IsVFSMapped);
14711471
EXPECT_TRUE(S->equivalent(*O->status("//root/foo/bar")));
14721472

14731473
SLower = O->status("//root/foo/bar");
14741474
EXPECT_EQ("//root/foo/bar", SLower->getName());
14751475
EXPECT_TRUE(S->equivalent(*SLower));
1476-
EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1476+
EXPECT_FALSE(SLower->IsVFSMapped);
14771477

14781478
// file in remapped directory
14791479
S = O->status("//root/mappeddir/a");
14801480
ASSERT_FALSE(S.getError());
1481-
EXPECT_FALSE(S->isDirectory());
1482-
EXPECT_TRUE(S->ExposesExternalVFSPath);
1483-
EXPECT_EQ("//root/foo/bar/a", S->getName());
1481+
ASSERT_FALSE(S->isDirectory());
1482+
ASSERT_TRUE(S->IsVFSMapped);
1483+
ASSERT_EQ("//root/foo/bar/a", S->getName());
14841484

14851485
// file in remapped directory, with use-external-name=false
14861486
S = O->status("//root/mappeddir2/a");
14871487
ASSERT_FALSE(S.getError());
1488-
EXPECT_FALSE(S->isDirectory());
1489-
EXPECT_FALSE(S->ExposesExternalVFSPath);
1490-
EXPECT_EQ("//root/mappeddir2/a", S->getName());
1488+
ASSERT_FALSE(S->isDirectory());
1489+
ASSERT_TRUE(S->IsVFSMapped);
1490+
ASSERT_EQ("//root/mappeddir2/a", S->getName());
14911491

14921492
// file contents in remapped directory
14931493
OpenedF = O->openFileForRead("//root/mappeddir/a");
14941494
ASSERT_FALSE(OpenedF.getError());
14951495
OpenedS = (*OpenedF)->status();
14961496
ASSERT_FALSE(OpenedS.getError());
14971497
EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1498-
EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1498+
EXPECT_TRUE(OpenedS->IsVFSMapped);
14991499

15001500
// file contents in remapped directory, with use-external-name=false
15011501
OpenedF = O->openFileForRead("//root/mappeddir2/a");
15021502
ASSERT_FALSE(OpenedF.getError());
15031503
OpenedS = (*OpenedF)->status();
15041504
ASSERT_FALSE(OpenedS.getError());
15051505
EXPECT_EQ("//root/mappeddir2/a", OpenedS->getName());
1506-
EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
1506+
EXPECT_TRUE(OpenedS->IsVFSMapped);
15071507

15081508
// broken mapping
15091509
EXPECT_EQ(O->status("//root/file2").getError(),
@@ -1535,20 +1535,20 @@ TEST_F(VFSFromYAMLTest, MappedRoot) {
15351535
ErrorOr<vfs::Status> S = O->status("//mappedroot/a");
15361536
ASSERT_FALSE(S.getError());
15371537
EXPECT_EQ("//root/foo/bar/a", S->getName());
1538-
EXPECT_TRUE(S->ExposesExternalVFSPath);
1538+
EXPECT_TRUE(S->IsVFSMapped);
15391539

15401540
ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
15411541
EXPECT_EQ("//root/foo/bar/a", SLower->getName());
15421542
EXPECT_TRUE(S->equivalent(*SLower));
1543-
EXPECT_FALSE(SLower->ExposesExternalVFSPath);
1543+
EXPECT_FALSE(SLower->IsVFSMapped);
15441544

15451545
// file after opening
15461546
auto OpenedF = O->openFileForRead("//mappedroot/a");
15471547
ASSERT_FALSE(OpenedF.getError());
15481548
auto OpenedS = (*OpenedF)->status();
15491549
ASSERT_FALSE(OpenedS.getError());
15501550
EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
1551-
EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1551+
EXPECT_TRUE(OpenedS->IsVFSMapped);
15521552

15531553
EXPECT_EQ(0, NumDiagnostics);
15541554
}
@@ -1696,12 +1696,12 @@ TEST_F(VFSFromYAMLTest, ReturnsRequestedPathVFSMiss) {
16961696
auto OpenedS = (*OpenedF)->status();
16971697
ASSERT_FALSE(OpenedS.getError());
16981698
EXPECT_EQ("a", OpenedS->getName());
1699-
EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
1699+
EXPECT_FALSE(OpenedS->IsVFSMapped);
17001700

17011701
auto DirectS = RemappedFS->status("a");
17021702
ASSERT_FALSE(DirectS.getError());
17031703
EXPECT_EQ("a", DirectS->getName());
1704-
EXPECT_FALSE(DirectS->ExposesExternalVFSPath);
1704+
EXPECT_FALSE(DirectS->IsVFSMapped);
17051705

17061706
EXPECT_EQ(0, NumDiagnostics);
17071707
}
@@ -1736,12 +1736,12 @@ TEST_F(VFSFromYAMLTest, ReturnsExternalPathVFSHit) {
17361736
auto OpenedS = (*OpenedF)->status();
17371737
ASSERT_FALSE(OpenedS.getError());
17381738
EXPECT_EQ("realname", OpenedS->getName());
1739-
EXPECT_TRUE(OpenedS->ExposesExternalVFSPath);
1739+
EXPECT_TRUE(OpenedS->IsVFSMapped);
17401740

17411741
auto DirectS = FS->status("vfsname");
17421742
ASSERT_FALSE(DirectS.getError());
17431743
EXPECT_EQ("realname", DirectS->getName());
1744-
EXPECT_TRUE(DirectS->ExposesExternalVFSPath);
1744+
EXPECT_TRUE(DirectS->IsVFSMapped);
17451745

17461746
EXPECT_EQ(0, NumDiagnostics);
17471747
}
@@ -1776,12 +1776,12 @@ TEST_F(VFSFromYAMLTest, ReturnsInternalPathVFSHit) {
17761776
auto OpenedS = (*OpenedF)->status();
17771777
ASSERT_FALSE(OpenedS.getError());
17781778
EXPECT_EQ("vfsname", OpenedS->getName());
1779-
EXPECT_FALSE(OpenedS->ExposesExternalVFSPath);
1779+
EXPECT_TRUE(OpenedS->IsVFSMapped);
17801780

17811781
auto DirectS = FS->status("vfsname");
17821782
ASSERT_FALSE(DirectS.getError());
17831783
EXPECT_EQ("vfsname", DirectS->getName());
1784-
EXPECT_FALSE(DirectS->ExposesExternalVFSPath);
1784+
EXPECT_TRUE(DirectS->IsVFSMapped);
17851785

17861786
EXPECT_EQ(0, NumDiagnostics);
17871787
}

0 commit comments

Comments
 (0)