[gcc r9-8365] libstdc++: Ensure root-dir converted to forward slash (PR93244)

Jonathan Wakely redi@gcc.gnu.org
Thu Mar 12 17:39:34 GMT 2020


https://gcc.gnu.org/g:362c8772e7779d9e4730e2e51628ccaadce98bd0

commit r9-8365-g362c8772e7779d9e4730e2e51628ccaadce98bd0
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 12 17:39:04 2020 +0000

    libstdc++: Ensure root-dir converted to forward slash (PR93244)
    
    Backport from mainline
    2020-01-13  Jonathan Wakely  <jwakely@redhat.com>
    
            PR libstdc++/93244
            * include/bits/fs_path.h (path::generic_string<C,A>)
            [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Convert root-dir to forward-slash.
            * testsuite/27_io/filesystem/path/generic/generic_string.cc: Check
            root-dir is converted to forward slash in generic pathname.
            * testsuite/27_io/filesystem/path/generic/utf.cc: New test.
            * testsuite/27_io/filesystem/path/generic/wchar_t.cc: New test.

Diff:
---
 libstdc++-v3/ChangeLog                             | 13 +++++
 libstdc++-v3/include/bits/fs_path.h                |  7 +++
 .../filesystem/path/generic/generic_string.cc      | 14 ++++-
 .../testsuite/27_io/filesystem/path/generic/utf.cc | 65 ++++++++++++++++++++++
 .../27_io/filesystem/path/generic/wchar_t.cc       | 65 ++++++++++++++++++++++
 5 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 45847172291..000ecbfbad1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,16 @@
+2020-03-12  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backport from mainline
+	2020-01-13  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/93244
+	* include/bits/fs_path.h (path::generic_string<C,A>)
+	[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Convert root-dir to forward-slash.
+	* testsuite/27_io/filesystem/path/generic/generic_string.cc: Check
+	root-dir is converted to forward slash in generic pathname.
+	* testsuite/27_io/filesystem/path/generic/utf.cc: New test.
+	* testsuite/27_io/filesystem/path/generic/wchar_t.cc: New test.
+
 2020-03-12  Release Manager
 
 	* GCC 9.3.0 released.
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 5dc624dbb1e..6b39c46ac6e 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -1073,6 +1073,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 	  bool __add_slash = false;
 	  for (auto& __elem : *this)
 	    {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+	      if (__elem._M_type() == _Type::_Root_dir)
+		{
+		  __str += __slash;
+		  continue;
+		}
+#endif
 	      if (__add_slash)
 		__str += __slash;
 	      __str += __elem._M_pathname;
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc
index 5a0c24c25c3..5caf079ed9b 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/generic_string.cc
@@ -1,7 +1,7 @@
 // { dg-options "-std=gnu++17" }
 // { dg-do run { target c++17 } }
 
-// Copyright (C) 2017-2019 Free Software Foundation, Inc.
+// Copyright (C) 2017-2020 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -46,8 +46,20 @@ test01()
   VERIFY( path("/a//b//.").generic_string() == "/a/b/." );
 }
 
+void
+test02()
+{
+  if constexpr (path::preferred_separator == L'\\')
+  {
+    // PR libstdc++/93244
+    VERIFY( path("C:\\foo\\bar").generic_string() == "C:/foo/bar" );
+    VERIFY( path("C://foo//bar").generic_string() == "C:/foo/bar" );
+  }
+}
+
 int
 main()
 {
   test01();
+  test02();
 }
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/generic/utf.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/utf.cc
new file mode 100644
index 00000000000..52afdb4497b
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/utf.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 2017-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// C++17 30.10.7.4.7 path generic format observers [fs.path.generic.obs]
+
+#include <filesystem>
+#include <testsuite_hooks.h>
+
+using std::filesystem::path;
+
+void
+test01()
+{
+  VERIFY( path().generic_u32string() == U"" );
+  VERIFY( path("/").generic_u32string() == U"/" );
+  VERIFY( path("////").generic_u32string() == U"/" );
+#ifdef __CYGWIN__
+  VERIFY( path("//a").generic_u32string() == U"//a" );
+  VERIFY( path("//a/").generic_u32string() == U"//a/" );
+  VERIFY( path("//a/b").generic_u32string() == U"//a/b" );
+#else
+  VERIFY( path("//a").generic_u32string() == U"/a" );
+  VERIFY( path("//a/").generic_u32string() == U"/a/" );
+  VERIFY( path("//a/b").generic_u32string() == U"/a/b" );
+#endif
+  VERIFY( path("/a//b").generic_u32string() == U"/a/b" );
+  VERIFY( path("/a//b/").generic_u32string() == U"/a/b/" );
+  VERIFY( path("/a//b//").generic_u32string() == U"/a/b/" );
+  VERIFY( path("/a//b//.").generic_u32string() == U"/a/b/." );
+}
+
+void
+test02()
+{
+  if constexpr (path::preferred_separator == L'\\')
+  {
+    // PR libstdc++/93244
+    VERIFY( path("C:\\foo\\bar").generic_u32string() == U"C:/foo/bar" );
+    VERIFY( path("C://foo//bar").generic_u32string() == U"C:/foo/bar" );
+  }
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/generic/wchar_t.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/wchar_t.cc
new file mode 100644
index 00000000000..7bb2f643043
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/generic/wchar_t.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 2017-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// C++17 30.10.7.4.7 path generic format observers [fs.path.generic.obs]
+
+#include <filesystem>
+#include <testsuite_hooks.h>
+
+using std::filesystem::path;
+
+void
+test01()
+{
+  VERIFY( path().generic_wstring() == L"" );
+  VERIFY( path("/").generic_wstring() == L"/" );
+  VERIFY( path("////").generic_wstring() == L"/" );
+#ifdef __CYGWIN__
+  VERIFY( path("//a").generic_wstring() == L"//a" );
+  VERIFY( path("//a/").generic_wstring() == L"//a/" );
+  VERIFY( path("//a/b").generic_wstring() == L"//a/b" );
+#else
+  VERIFY( path("//a").generic_wstring() == L"/a" );
+  VERIFY( path("//a/").generic_wstring() == L"/a/" );
+  VERIFY( path("//a/b").generic_wstring() == L"/a/b" );
+#endif
+  VERIFY( path("/a//b").generic_wstring() == L"/a/b" );
+  VERIFY( path("/a//b/").generic_wstring() == L"/a/b/" );
+  VERIFY( path("/a//b//").generic_wstring() == L"/a/b/" );
+  VERIFY( path("/a//b//.").generic_wstring() == L"/a/b/." );
+}
+
+void
+test02()
+{
+  if constexpr (path::preferred_separator == L'\\')
+  {
+    // PR libstdc++/93244
+    VERIFY( path("C:\\foo\\bar").generic_wstring() == L"C:/foo/bar" );
+    VERIFY( path("C://foo//bar").generic_wstring() == L"C:/foo/bar" );
+  }
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}


More information about the Libstdc++-cvs mailing list