summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2014-05-20 22:12:58 +0000
committerJustin Bogner <mail@justinbogner.com>2014-05-20 22:12:58 +0000
commit1c078f2b1f7420c1445e9cda13acf7d022560db6 (patch)
tree649dcb89b39ab855e41d69acef3916a2ec875992
parent38ff5677439dd524b0d8fc9fa9b418feaa92c100 (diff)
downloadbcm5719-llvm-1c078f2b1f7420c1445e9cda13acf7d022560db6.tar.gz
bcm5719-llvm-1c078f2b1f7420c1445e9cda13acf7d022560db6.zip
VirtualFileSystem: Fix false positives in YAMLVFSWriter::containedIn
Checking if a path starts with another path isn't sufficient for determining if one is contained within the heirarchy of the other. We need to ensure that the substring ends at a directory boundary. llvm-svn: 209250
-rw-r--r--clang/lib/Basic/VirtualFileSystem.cpp11
-rw-r--r--clang/unittests/libclang/LibclangTest.cpp51
2 files changed, 61 insertions, 1 deletions
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp
index 24454b0192c..077370dcf42 100644
--- a/clang/lib/Basic/VirtualFileSystem.cpp
+++ b/clang/lib/Basic/VirtualFileSystem.cpp
@@ -928,7 +928,16 @@ YAMLVFSWriter::printContents(llvm::raw_ostream &OS, ArrayRef<MapEntry> Entries,
}
bool YAMLVFSWriter::containedIn(StringRef Parent, StringRef Path) {
- return Path.startswith(Parent);
+ using namespace llvm::sys;
+ // Compare each path component.
+ auto IParent = path::begin(Parent), EParent = path::end(Parent);
+ for (auto IChild = path::begin(Path), EChild = path::end(Path);
+ IParent != EParent && IChild != EChild; ++IParent, ++IChild) {
+ if (*IParent != *IChild)
+ return false;
+ }
+ // Have we exhausted the parent path?
+ return IParent == EParent;
}
StringRef YAMLVFSWriter::containedPart(StringRef Parent, StringRef Path) {
diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index 50d4c489f23..61578a4801c 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -184,6 +184,57 @@ TEST(libclang, VirtualFileOverlay) {
T.map("/path/virtual/foo.h", "/real/foo.h");
clang_VirtualFileOverlay_setCaseSensitivity(T.VFO, false);
}
+ {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/foo\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"bar\",\n"
+ " 'external-contents': \"/real/bar\"\n"
+ " },\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"bar.h\",\n"
+ " 'external-contents': \"/real/bar.h\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/foobar\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"baz.h\",\n"
+ " 'external-contents': \"/real/baz.h\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foobarbaz.h\",\n"
+ " 'external-contents': \"/real/foobarbaz.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/foo/bar.h", "/real/bar.h");
+ T.map("/path/foo/bar", "/real/bar");
+ T.map("/path/foobar/baz.h", "/real/baz.h");
+ T.map("/path/foobarbaz.h", "/real/foobarbaz.h");
+ }
}
TEST(libclang, ModuleMapDescriptor) {
OpenPOWER on IntegriCloud