This is an archive of the discontinued LLVM Phabricator instance.

[VFS][WIP] More consistent handling of hybrid paths of Windows+Posix styles
Needs ReviewPublic

Authored by amccarth on Feb 18 2020, 9:42 AM.

Details

Reviewers
john.brawn
rnk
Summary

This is a counter-proposal to the fix suggested in

https://reviews.llvm.org/D74488

VFS paths can be a hybrid of Windows and Posix styles, so the sys::path methods sometimes cannot handle them. This generalizes the VFS-specific canonicalize function to remove traversal components from these possibly hybrid paths.

THIS NEEDS TESTS.

Diff Detail

Event Timeline

amccarth created this revision.Feb 18 2020, 9:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 18 2020, 9:42 AM
Herald added a subscriber: hiraditya. · View Herald Transcript

This causes a lot of test failures in llvm/unittests/Support/VirtualFileSystemTest.cpp. A lot of them use //root as a root directory, and e.g. looking at the MappedFiles test what's happening is:

  • //root/foo/bar/a is added to the DummyFileSystem
  • getFromYAMLString used on a YAML string that maps //root/file1 to //root/foo/bar/a
  • The //root/foo/bar/a is canonicalized to /root/foo/bar/a
  • O->status("//root/file1") matches the //root/file1 in the YAML, but the subsequent lookup tries to find /root/foo/bar/a which doesn't match the //root/foo/bar/a that was added to the DummyFileSystem so we get a "file not found" error

That's strange. I thought I'd run all the LLVM and Clang VFS tests before posting this patch.

I'll look into it some more when I get a chance. I was not aware that Posix treats (exactly) two slashes at the root as "special." These VFS hybrid paths are really a pain, since a double backslash at the root means a UNC path, but we mostly treat slashes and backslashes as interchangeable. What a mess.

This causes a lot of test failures in llvm/unittests/Support/VirtualFileSystemTest.cpp. A lot of them use //root as a root directory, and e.g. looking at the MappedFiles test what's happening is:

  • //root/foo/bar/a is added to the DummyFileSystem
  • getFromYAMLString used on a YAML string that maps //root/file1 to //root/foo/bar/a
  • The //root/foo/bar/a is canonicalized to /root/foo/bar/a
  • O->status("//root/file1") matches the //root/file1 in the YAML, but the subsequent lookup tries to find /root/foo/bar/a which doesn't match the //root/foo/bar/a that was added to the DummyFileSystem so we get a "file not found" error

I cannot reproduce the problem you're reporting. For example:

D:\src\llvm\build\ninja_dbg\unittests\Support\SupportTests.exe --gtest_filter=VFSFromYAMLTest.MappedFiles
Note: Google Test filter = VFSFromYAMLTest.MappedFiles
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from VFSFromYAMLTest
[ RUN      ] VFSFromYAMLTest.MappedFiles
[       OK ] VFSFromYAMLTest.MappedFiles (3 ms)
[----------] 1 test from VFSFromYAMLTest (10 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (27 ms total)
[  PASSED  ] 1 test.

In fact, if I make canonicalize preserve both slashes at the root whenever they exist, then I get failures even creating the file system from the yaml because sys::path::is_absolute no longer thinks //root/file1 is an absolute path.

I'm showing the result from VFSFromYAMLTest.MappedFiles because that's the specific example you gave. But all of the clang VFS tests and LLVM Support tests pass for me with this patch.

Running that command (with this patch applied to trunk revision 56ac9d30d35632969baa39829ebc8465ed5937ef) I get

Note: Google Test filter = VFSFromYAMLTest.MappedFiles
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from VFSFromYAMLTest
[ RUN      ] VFSFromYAMLTest.MappedFiles
C:\Users\johbra01\llvm-project\llvm\unittests\Support\VirtualFileSystemTest.cpp(1411): error: Value of: S.getError()
  Actual: true
Expected: false
[  FAILED  ] VFSFromYAMLTest.MappedFiles (30 ms)
[----------] 1 test from VFSFromYAMLTest (94 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (232 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] VFSFromYAMLTest.MappedFiles

 1 FAILED TEST

And I also see this same failure on Linux. I'll try looking into this some more to make sure I'm not doing something strange somehow.

Doing a clean checkout and build on Linux using the following commands I get the same test error:

git clone https://github.com/llvm/llvm-project.git
wget https://reviews.llvm.org/file/download/tiyftt33uo7cki54v443/PHID-FILE-yq35g4b6fbvssmn5il2f/D74777.diff
patch -d llvm-project -p0 < D74777.diff
mkdir build
cd build
cmake ../llvm-project/llvm/
make SupportTests
./unittests/Support/SupportTests --gtest_filter=VFSFromYAMLTest.MappedFiles