[libcxx-commits] [libcxx] [libc++] Fix different slashes confuses lexically_proximate and lexically_relative (PR #99780)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 25 21:38:45 PDT 2024
https://github.com/RichardLuo0 updated https://github.com/llvm/llvm-project/pull/99780
>From 9774e7e97eb01e8b33c1820e9daec3b1fd64dce5 Mon Sep 17 00:00:00 2001
From: RichardLuo <22096448+RichardLuo0 at users.noreply.github.com>
Date: Mon, 22 Jul 2024 13:12:33 +0800
Subject: [PATCH 1/3] [libc++] fix the state when its in root dir in
lexically_relative
---
libcxx/src/filesystem/path.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/src/filesystem/path.cpp b/libcxx/src/filesystem/path.cpp
index b2019521377ed..eefd8b22dfd69 100644
--- a/libcxx/src/filesystem/path.cpp
+++ b/libcxx/src/filesystem/path.cpp
@@ -267,7 +267,7 @@ path path::lexically_relative(const path& base) const {
// Find the first mismatching element
auto PP = PathParser::CreateBegin(__pn_);
auto PPBase = PathParser::CreateBegin(base.__pn_);
- while (PP && PPBase && PP.State_ == PPBase.State_ && *PP == *PPBase) {
+ while (PP && PPBase && PP.State_ == PPBase.State_ && (*PP == *PPBase || PP.inRootDir())) {
++PP;
++PPBase;
}
>From 77beb3514ac12dd284aed5d4d771174b49a1b7f1 Mon Sep 17 00:00:00 2001
From: RichardLuo <22096448+RichardLuo0 at users.noreply.github.com>
Date: Fri, 26 Jul 2024 12:36:46 +0800
Subject: [PATCH 2/3] [libc++] add lexically_relative and _proximate test
---
.../path.gen/lexically_relative_and_proximate.pass.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
index 42fa813ada4a5..06954fe876e55 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
@@ -41,9 +41,11 @@ int main(int, char**) {
#ifdef _WIN32
{"//net/", "//net", ""},
{"//net", "//net/", ""},
+ {"C:\\a\\b", "C:/a", "b"},
#else
{"//net/", "//net", "."},
{"//net", "//net/", "."},
+ {"C:\\a\\b", "C:/a", "../../C:\\a\\b"},
#endif
{"//base", "a", ""},
{"a", "a", "."},
>From 9f2b4b6c787e0a143d34fcebae8267617fe9e73b Mon Sep 17 00:00:00 2001
From: RichardLuo <22096448+RichardLuo0 at users.noreply.github.com>
Date: Fri, 26 Jul 2024 12:37:53 +0800
Subject: [PATCH 3/3] [libc++] fix incorrect hash value in root dir
---
libcxx/src/filesystem/path.cpp | 3 +-
.../path.member/path.compare.pass.cpp | 60 +++++++++++--------
2 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/libcxx/src/filesystem/path.cpp b/libcxx/src/filesystem/path.cpp
index eefd8b22dfd69..58742442bae6b 100644
--- a/libcxx/src/filesystem/path.cpp
+++ b/libcxx/src/filesystem/path.cpp
@@ -368,7 +368,8 @@ size_t hash_value(const path& __p) noexcept {
size_t hash_value = 0;
hash<string_view_t> hasher;
while (PP) {
- hash_value = __hash_combine(hash_value, hasher(*PP));
+ string_view_t Part = PP.inRootDir() ? PATHSTR("/") : *PP;
+ hash_value = __hash_combine(hash_value, hasher(Part));
++PP;
}
return hash_value;
diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
index 99f55d3b17f1b..3bebf38a2a7c3 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp
@@ -47,13 +47,20 @@ struct PathCompareTest {
int expect;
};
-#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
-#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
-#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
-const PathCompareTest CompareTestCases[] =
-{
- {"", "", 0},
+#define LONGA \
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \
+ "AAAAAAAA"
+#define LONGB \
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" \
+ "BBBBBBBB"
+#define LONGC \
+ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" \
+ "CCCCCCCC"
+#define LONGD \
+ "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" \
+ "DDDDDDDD"
+const PathCompareTest CompareTestCases[] = {
+ {"", "", 0},
{"a", "", 1},
{"", "a", -1},
{"a/b/c", "a/b/c", 0},
@@ -62,14 +69,19 @@ const PathCompareTest CompareTestCases[] =
{"a/b", "a/b/c", -1},
{"a/b/c", "a/b", 1},
{"a/b/", "a/b/.", -1},
- {"a/b/", "a/b", 1},
+ {"a/b/", "a/b", 1},
{"a/b//////", "a/b/////.", -1},
{"a/.././b", "a///..//.////b", 0},
{"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
- {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
- {"/foo/bar/", "/foo/bar", 1}, // trailing separator
+ {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
+ {"/foo/bar/", "/foo/bar", 1}, // trailing separator
{"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0.
- {"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
+ {"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
+#ifdef _WIN32
+ {"C:/a", "C:\\a", 0},
+#else
+ {"C:/a", "C:\\a", -1},
+#endif
{("//" LONGA "////" LONGB "/" LONGC "///" LONGD), ("//" LONGA "/" LONGB "/" LONGC "/" LONGD), 0},
{(LONGA "/" LONGB "/" LONGC), (LONGA "/" LONGB "/" LONGB), 1}
@@ -79,23 +91,19 @@ const PathCompareTest CompareTestCases[] =
#undef LONGC
#undef LONGD
-static inline int normalize_ret(int ret)
-{
- return ret < 0 ? -1 : (ret > 0 ? 1 : 0);
-}
+static inline int normalize_ret(int ret) { return ret < 0 ? -1 : (ret > 0 ? 1 : 0); }
-void test_compare_basic()
-{
+void test_compare_basic() {
using namespace fs;
- for (auto const & TC : CompareTestCases) {
+ for (auto const& TC : CompareTestCases) {
const path p1(TC.LHS);
const path p2(TC.RHS);
std::string RHS(TC.RHS);
const path::string_type R(RHS.begin(), RHS.end());
const std::basic_string_view<path::value_type> RV(R);
- const path::value_type *Ptr = R.c_str();
- const int E = TC.expect;
- { // compare(...) functions
+ const path::value_type* Ptr = R.c_str();
+ const int E = TC.expect;
+ { // compare(...) functions
DisableAllocationGuard g; // none of these operations should allocate
// check runtime results
@@ -113,7 +121,7 @@ void test_compare_basic()
// check signatures
ASSERT_NOEXCEPT(p1.compare(p2));
}
- { // comparison operators
+ { // comparison operators
DisableAllocationGuard g; // none of these operations should allocate
// check signatures
@@ -180,14 +188,14 @@ void test_compare_elements() {
auto BuildPath = [](std::vector<std::string> const& Elems) {
fs::path p;
- for (auto &E : Elems)
+ for (auto& E : Elems)
p /= E;
return p;
};
- for (auto &TC : TestCases) {
- fs::path LHS = BuildPath(TC.LHSElements);
- fs::path RHS = BuildPath(TC.RHSElements);
+ for (auto& TC : TestCases) {
+ fs::path LHS = BuildPath(TC.LHSElements);
+ fs::path RHS = BuildPath(TC.RHSElements);
const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements);
assert(ExpectCmp == TC.Expect);
const int GotCmp = normalize_ret(LHS.compare(RHS));
More information about the libcxx-commits
mailing list