Fix an inconsistency in treatment of trailing / in path::const_iterator
authorBen Langmuir <blangmuir@apple.com>
Wed, 5 Mar 2014 19:56:30 +0000 (19:56 +0000)
committerBen Langmuir <blangmuir@apple.com>
Wed, 5 Mar 2014 19:56:30 +0000 (19:56 +0000)
When using a //net/ path, we were transforming the trailing / into a '.'
when the path was just the root path and we were iterating backwards.
Forwards iteration and other kinds of root path (C:\, /) were already
correct.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202999 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/Path.cpp
unittests/Support/Path.cpp

index 1bd94a76faf7934bc1047140c1960c9ba969b06c..6fdad22158d13b09032774c90df2014eff695606 100644 (file)
@@ -307,21 +307,18 @@ const_iterator &const_iterator::operator++() {
 }
 
 const_iterator &const_iterator::operator--() {
-  // If we're at the end and the previous char was a '/', return '.'.
+  // If we're at the end and the previous char was a '/', return '.' unless
+  // we are the root path.
+  size_t root_dir_pos = root_dir_start(Path);
   if (Position == Path.size() &&
-      Path.size() > 1 &&
-      is_separator(Path[Position - 1])
-#ifdef LLVM_ON_WIN32
-      && Path[Position - 2] != ':'
-#endif
-      ) {
+      Path.size() > root_dir_pos + 1 &&
+      is_separator(Path[Position - 1])) {
     --Position;
     Component = ".";
     return *this;
   }
 
   // Skip separators unless it's the root directory.
-  size_t root_dir_pos = root_dir_start(Path);
   size_t end_pos = Position;
 
   while(end_pos > 0 &&
index c4067b9137ee86f2e279129f8de510d915e3caab..29a77f3780d9fa7fa2b8b46e0a33dcfeb9deafde 100644 (file)
@@ -210,6 +210,35 @@ TEST(Support, AbsolutePathIteratorWin32) {
 }
 #endif // LLVM_ON_WIN32
 
+TEST(Support, AbsolutePathIteratorEnd) {
+  // Trailing slashes are converted to '.' unless they are part of the root path.
+  SmallVector<StringRef, 4> Paths;
+  Paths.push_back("/foo/");
+  Paths.push_back("/foo//");
+  Paths.push_back("//net//");
+#ifdef LLVM_ON_WIN32
+  Paths.push_back("c:\\\\");
+#endif
+
+  for (StringRef Path : Paths) {
+    StringRef LastComponent = *--path::end(Path);
+    EXPECT_EQ(".", LastComponent);
+  }
+
+  SmallVector<StringRef, 3> RootPaths;
+  RootPaths.push_back("/");
+  RootPaths.push_back("//net/");
+#ifdef LLVM_ON_WIN32
+  RootPaths.push_back("c:\\");
+#endif
+
+  for (StringRef Path : RootPaths) {
+    StringRef LastComponent = *--path::end(Path);
+    EXPECT_EQ(1u, LastComponent.size());
+    EXPECT_TRUE(path::is_separator(LastComponent[0]));
+  }
+}
+
 TEST(Support, HomeDirectory) {
 #ifdef LLVM_ON_UNIX
   // This test only makes sense on Unix if $HOME is set.