public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] Add noexcept to Filesystem TS operators
@ 2016-04-19 18:03 Jonathan Wakely
  2016-04-19 18:06 ` [patch] libstdc++/70609 fix filesystem::copy() Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-04-19 18:03 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 301 bytes --]

This isn't terribly important, but these operators might as well be
noexcept, and committing it now isn't going to cause any problems
backporting anything to gcc-6-branch at the last minute.

I have a couple more patches for Filesystem TS issues coming too.

Tested x86_64-linux, committed to trunk.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 6953 bytes --]

commit ac48e4cb8e5ff17a03dd478077568a8fd023abde
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Apr 19 18:31:43 2016 +0100

    Add noexcept to Filesystem TS operators
    
    	* include/experimental/bits/fs_fwd.h (operator&, operator|, operator^,
    	operator~ operator&=, operator|=, operator^=): Add noexcept to
    	overloaded operators for copy_options, perms and directory_options.
    	* src/filesystem/ops.cc (make_file_type, make_file_status,
    	is_not_found_errno, file_time): Add noexcept.

diff --git a/libstdc++-v3/include/experimental/bits/fs_fwd.h b/libstdc++-v3/include/experimental/bits/fs_fwd.h
index 1482e18..57aa4d3 100644
--- a/libstdc++-v3/include/experimental/bits/fs_fwd.h
+++ b/libstdc++-v3/include/experimental/bits/fs_fwd.h
@@ -93,7 +93,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   };
 
   constexpr copy_options
-  operator&(copy_options __x, copy_options __y)
+  operator&(copy_options __x, copy_options __y) noexcept
   {
     using __utype = typename std::underlying_type<copy_options>::type;
     return static_cast<copy_options>(
@@ -101,7 +101,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr copy_options
-  operator|(copy_options __x, copy_options __y)
+  operator|(copy_options __x, copy_options __y) noexcept
   {
     using __utype = typename std::underlying_type<copy_options>::type;
     return static_cast<copy_options>(
@@ -109,7 +109,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr copy_options
-  operator^(copy_options __x, copy_options __y)
+  operator^(copy_options __x, copy_options __y) noexcept
   {
     using __utype = typename std::underlying_type<copy_options>::type;
     return static_cast<copy_options>(
@@ -117,22 +117,22 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr copy_options
-  operator~(copy_options __x)
+  operator~(copy_options __x) noexcept
   {
     using __utype = typename std::underlying_type<copy_options>::type;
     return static_cast<copy_options>(~static_cast<__utype>(__x));
   }
 
   inline copy_options&
-  operator&=(copy_options& __x, copy_options __y)
+  operator&=(copy_options& __x, copy_options __y) noexcept
   { return __x = __x & __y; }
 
   inline copy_options&
-  operator|=(copy_options& __x, copy_options __y)
+  operator|=(copy_options& __x, copy_options __y) noexcept
   { return __x = __x | __y; }
 
   inline copy_options&
-  operator^=(copy_options& __x, copy_options __y)
+  operator^=(copy_options& __x, copy_options __y) noexcept
   { return __x = __x ^ __y; }
 
 
@@ -163,7 +163,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   };
 
   constexpr perms
-  operator&(perms __x, perms __y)
+  operator&(perms __x, perms __y) noexcept
   {
     using __utype = typename std::underlying_type<perms>::type;
     return static_cast<perms>(
@@ -171,7 +171,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr perms
-  operator|(perms __x, perms __y)
+  operator|(perms __x, perms __y) noexcept
   {
     using __utype = typename std::underlying_type<perms>::type;
     return static_cast<perms>(
@@ -179,7 +179,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr perms
-  operator^(perms __x, perms __y)
+  operator^(perms __x, perms __y) noexcept
   {
     using __utype = typename std::underlying_type<perms>::type;
     return static_cast<perms>(
@@ -187,22 +187,22 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr perms
-  operator~(perms __x)
+  operator~(perms __x) noexcept
   {
     using __utype = typename std::underlying_type<perms>::type;
     return static_cast<perms>(~static_cast<__utype>(__x));
   }
 
   inline perms&
-  operator&=(perms& __x, perms __y)
+  operator&=(perms& __x, perms __y) noexcept
   { return __x = __x & __y; }
 
   inline perms&
-  operator|=(perms& __x, perms __y)
+  operator|=(perms& __x, perms __y) noexcept
   { return __x = __x | __y; }
 
   inline perms&
-  operator^=(perms& __x, perms __y)
+  operator^=(perms& __x, perms __y) noexcept
   { return __x = __x ^ __y; }
 
   // Bitmask type
@@ -211,7 +211,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   };
 
   constexpr directory_options
-  operator&(directory_options __x, directory_options __y)
+  operator&(directory_options __x, directory_options __y) noexcept
   {
     using __utype = typename std::underlying_type<directory_options>::type;
     return static_cast<directory_options>(
@@ -219,7 +219,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr directory_options
-  operator|(directory_options __x, directory_options __y)
+  operator|(directory_options __x, directory_options __y) noexcept
   {
     using __utype = typename std::underlying_type<directory_options>::type;
     return static_cast<directory_options>(
@@ -227,7 +227,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr directory_options
-  operator^(directory_options __x, directory_options __y)
+  operator^(directory_options __x, directory_options __y) noexcept
   {
     using __utype = typename std::underlying_type<directory_options>::type;
     return static_cast<directory_options>(
@@ -235,22 +235,22 @@ _GLIBCXX_END_NAMESPACE_CXX11
   }
 
   constexpr directory_options
-  operator~(directory_options __x)
+  operator~(directory_options __x) noexcept
   {
     using __utype = typename std::underlying_type<directory_options>::type;
     return static_cast<directory_options>(~static_cast<__utype>(__x));
   }
 
   inline directory_options&
-  operator&=(directory_options& __x, directory_options __y)
+  operator&=(directory_options& __x, directory_options __y) noexcept
   { return __x = __x & __y; }
 
   inline directory_options&
-  operator|=(directory_options& __x, directory_options __y)
+  operator|=(directory_options& __x, directory_options __y) noexcept
   { return __x = __x | __y; }
 
   inline directory_options&
-  operator^=(directory_options& __x, directory_options __y)
+  operator^=(directory_options& __x, directory_options __y) noexcept
   { return __x = __x ^ __y; }
 
   typedef chrono::time_point<chrono::system_clock> file_time_type;
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index c32197e..756e140 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -249,7 +249,7 @@ namespace
   typedef struct ::stat stat_type;
 
   inline fs::file_type
-  make_file_type(const stat_type& st)
+  make_file_type(const stat_type& st) noexcept
   {
     using fs::file_type;
 #ifdef _GLIBCXX_HAVE_S_ISREG
@@ -273,7 +273,7 @@ namespace
   }
 
   inline fs::file_status
-  make_file_status(const stat_type& st)
+  make_file_status(const stat_type& st) noexcept
   {
     return fs::file_status{
 	make_file_type(st),
@@ -282,13 +282,13 @@ namespace
   }
 
   inline bool
-  is_not_found_errno(int err)
+  is_not_found_errno(int err) noexcept
   {
     return err == ENOENT || err == ENOTDIR;
   }
 
   inline fs::file_time_type
-  file_time(const stat_type& st)
+  file_time(const stat_type& st) noexcept
   {
     using namespace std::chrono;
     return fs::file_time_type{

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch] libstdc++/70609 fix filesystem::copy()
  2016-04-19 18:03 [patch] Add noexcept to Filesystem TS operators Jonathan Wakely
@ 2016-04-19 18:06 ` Jonathan Wakely
  2016-04-19 18:08   ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-04-19 18:06 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 493 bytes --]

The conditional code in filesystem::copy() that uses stdio_filebuf
didn't handle the case where the file to be copied is empty, and so
the ostream insertion doesn't do anything. I was also failing to check
for errors when closing the files.

Rather embarassingly, the copy.cc test was actually a duplicate of
absolute.cc and wasn't testing the copy function at all.

I also found some defects in the spec of filesystem::copy(), which
I've reported.

Tested x86_64-linux, committed to trunk.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 7973 bytes --]

commit 461aaa6fb392aad7fc0e2c210b0b493b9335b38c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Apr 19 18:32:03 2016 +0100

    libstdc++/70609 fix filesystem::copy()
    
    	PR libstdc++/70609
    	* src/filesystem/ops.cc (close_fd): New function.
    	(do_copy_file): Set permissions before copying file contents. Check
    	result of closing file descriptors. Don't copy streambuf when file
    	is empty.
    	(copy(const path&, const path&, copy_options, error_code&)): Use
    	lstat for source file when copy_symlinks is set.
    	* testsuite/experimental/filesystem/operations/copy.cc: Test copy().

diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 756e140..aa26caf 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -300,6 +300,17 @@ namespace
     };
   }
 
+  // Returns true if the file descriptor was successfully closed,
+  // otherwise returns false and the reason will be in errno.
+  inline bool
+  close_fd(int fd)
+  {
+    while (::close(fd))
+      if (errno != EINTR)
+	return false;
+    return true;
+  }
+
   bool
   do_copy_file(const fs::path& from, const fs::path& to,
 	       fs::copy_options option,
@@ -376,7 +387,8 @@ namespace
       }
 
     struct CloseFD {
-      ~CloseFD() { if (fd != -1) ::close(fd); }
+      ~CloseFD() { if (fd != -1) close_fd(fd); }
+      bool close() { return close_fd(std::exchange(fd, -1)); }
       int fd;
     };
 
@@ -401,23 +413,6 @@ namespace
 	return false;
       }
 
-#ifdef _GLIBCXX_USE_SENDFILE
-    auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size);
-    if (n != from_st->st_size)
-      {
-	ec.assign(errno, std::generic_category());
-	return false;
-      }
-#else
-    __gnu_cxx::stdio_filebuf<char> sbin(in.fd, std::ios::in);
-    __gnu_cxx::stdio_filebuf<char> sbout(out.fd, std::ios::out);
-    if ( !(std::ostream(&sbout) << &sbin) )
-      {
-	ec = std::make_error_code(std::errc::io_error);
-	return false;
-      }
-#endif
-
 #ifdef _GLIBCXX_USE_FCHMOD
     if (::fchmod(out.fd, from_st->st_mode))
 #elif _GLIBCXX_USE_FCHMODAT
@@ -429,6 +424,38 @@ namespace
 	ec.assign(errno, std::generic_category());
 	return false;
       }
+
+#ifdef _GLIBCXX_USE_SENDFILE
+    const auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size);
+    if (n != from_st->st_size)
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+    if (!out.close() || !in.close())
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+#else
+    __gnu_cxx::stdio_filebuf<char> sbin(in.fd, std::ios::in);
+    __gnu_cxx::stdio_filebuf<char> sbout(out.fd, std::ios::out);
+    if (sbin.is_open())
+      in.fd = -1;
+    if (sbout.is_open())
+      out.fd = -1;
+    if (from_st->st_size && !(std::ostream(&sbout) << &sbin))
+      {
+	ec = std::make_error_code(std::errc::io_error);
+	return false;
+      }
+    if (sbout.close() || sbin.close())
+      {
+	ec.assign(errno, std::generic_category());
+	return false;
+      }
+#endif
+
     ec.clear();
     return true;
   }
@@ -439,13 +466,15 @@ void
 fs::copy(const path& from, const path& to, copy_options options,
 	 error_code& ec) noexcept
 {
-  bool skip_symlinks = is_set(options, copy_options::skip_symlinks);
-  bool create_symlinks = is_set(options, copy_options::create_symlinks);
-  bool use_lstat = create_symlinks || skip_symlinks;
+  const bool skip_symlinks = is_set(options, copy_options::skip_symlinks);
+  const bool create_symlinks = is_set(options, copy_options::create_symlinks);
+  const bool copy_symlinks = is_set(options, copy_options::copy_symlinks);
+  const bool use_lstat = create_symlinks || skip_symlinks;
 
   file_status f, t;
   stat_type from_st, to_st;
-  if (use_lstat
+  // N4099 doesn't check copy_symlinks here, but I think that's a defect.
+  if (use_lstat || copy_symlinks
       ? ::lstat(from.c_str(), &from_st)
       : ::stat(from.c_str(), &from_st))
     {
@@ -488,7 +517,7 @@ fs::copy(const path& from, const path& to, copy_options options,
     {
       if (skip_symlinks)
 	ec.clear();
-      else if (!exists(t) && is_set(options, copy_options::copy_symlinks))
+      else if (!exists(t) && copy_symlinks)
 	copy_symlink(from, to, ec);
       else
 	// Not clear what should be done here.
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
index 9e89002..a5f6a3e 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
@@ -21,34 +21,127 @@
 // 15.3 Copy [fs.op.copy]
 
 #include <experimental/filesystem>
+#include <fstream>
 #include <testsuite_fs.h>
 #include <testsuite_hooks.h>
 
-using std::experimental::filesystem::path;
+namespace fs = std::experimental::filesystem;
 
+// Test error conditions.
 void
 test01()
 {
   bool test __attribute__((unused)) = false;
 
-  for (const path& p : __gnu_test::test_paths)
-    VERIFY( absolute(p).is_absolute() );
+  auto p = __gnu_test::nonexistent_path();
+  std::error_code ec;
+
+  VERIFY( !fs::exists(p) );
+  fs::copy(p, ".", fs::copy_options::none, ec);
+  VERIFY( ec );
+
+  ec.clear();
+  fs::copy(".", ".", fs::copy_options::none, ec);
+  VERIFY( ec );
+
+  std::ofstream{p.native()};
+  VERIFY( fs::is_directory(".") );
+  VERIFY( fs::is_regular_file(p) );
+  ec.clear();
+  fs::copy(".", p, fs::copy_options::none, ec);
+  VERIFY( ec );
+
+  remove(p, ec);
 }
 
+// Test is_symlink(f) case.
 void
 test02()
 {
   bool test __attribute__((unused)) = false;
 
-  path p1("/");
-  VERIFY( absolute(p1) == p1 );
-  VERIFY( absolute(p1, "/bar") == p1 );
-  path p2("/foo");
-  VERIFY( absolute(p2) == p2 );
-  VERIFY( absolute(p2, "/bar") == p2 );
-  path p3("foo");
-  VERIFY( absolute(p3) != p3 );
-  VERIFY( absolute(p3, "/bar") == "/bar/foo" );
+  auto from = __gnu_test::nonexistent_path();
+  auto to = __gnu_test::nonexistent_path();
+  std::error_code ec;
+
+  fs::create_symlink(".", from, ec);
+  VERIFY( !ec );
+  VERIFY( fs::exists(from) );
+
+  fs::copy(from, to, fs::copy_options::skip_symlinks, ec);
+  VERIFY( !ec );
+  VERIFY( !fs::exists(to) );
+
+  fs::copy(from, to, fs::copy_options::skip_symlinks, ec);
+  VERIFY( !ec );
+  VERIFY( !fs::exists(to) );
+
+  fs::copy(from, to,
+           fs::copy_options::skip_symlinks|fs::copy_options::copy_symlinks,
+           ec);
+  VERIFY( !ec );
+  VERIFY( !fs::exists(to) );
+
+  fs::copy(from, to, fs::copy_options::copy_symlinks, ec);
+  VERIFY( !ec );
+  VERIFY( fs::exists(to) );
+
+  fs::copy(from, to, fs::copy_options::copy_symlinks, ec);
+  VERIFY( ec );
+
+  remove(from, ec);
+  remove(to, ec);
+}
+
+// Test is_regular_file(f) case.
+void
+test03()
+{
+  bool test __attribute__((unused)) = false;
+
+  auto from = __gnu_test::nonexistent_path();
+  auto to = __gnu_test::nonexistent_path();
+
+  // test empty file
+  std::ofstream{from.native()};
+  VERIFY( fs::exists(from) );
+  VERIFY( fs::file_size(from) == 0 );
+  fs::copy(from, to);
+  VERIFY( fs::exists(to) );
+  VERIFY( fs::file_size(to) == 0 );
+
+  remove(to);
+  VERIFY( !fs::exists(to) );
+  std::ofstream{from.native()} << "Hello, filesystem!";
+  VERIFY( fs::file_size(from) != 0 );
+  fs::copy(from, to);
+  VERIFY( fs::exists(to) );
+  VERIFY( fs::file_size(to) == fs::file_size(from) );
+}
+
+// Test is_directory(f) case.
+void
+test04()
+{
+  bool test __attribute__((unused)) = false;
+
+  auto from = __gnu_test::nonexistent_path();
+  auto to = __gnu_test::nonexistent_path();
+  std::error_code ec;
+
+}
+
+// Test no-op cases.
+void
+test05()
+{
+  bool test __attribute__((unused)) = false;
+
+  auto to = __gnu_test::nonexistent_path();
+  std::error_code ec;
+
+  fs::copy("/", to, fs::copy_options::create_symlinks, ec);
+  VERIFY( !ec );
 }
 
 int
@@ -56,4 +149,7 @@ main()
 {
   test01();
   test02();
+  test03();
+  test04();
+  test05();
 }

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-04-19 18:06 ` [patch] libstdc++/70609 fix filesystem::copy() Jonathan Wakely
@ 2016-04-19 18:08   ` Jonathan Wakely
  2016-04-19 18:31     ` [patch] Fix configure test for sendfile() Jonathan Wakely
  2016-04-20 17:40     ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
  0 siblings, 2 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-04-19 18:08 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 166 bytes --]

This was reported as a bug in the Filesystem library, but it's
actually a problem in the codecvt_utf8 facet that it uses.

Tested x86_64-linux, committed to trunk.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 7535 bytes --]

commit 7f3a547a9e80556030e77ac090e2ad8e04e44abc
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Apr 19 18:32:17 2016 +0100

    libstdc++/69703 ignore endianness in codecvt_utf8
    
    	PR libstdc++/69703
    	* src/c++11/codecvt.cc (__codecvt_utf8_base<char16_t>::do_in)):
    	Override endianness bit in mode.
    	* testsuite/22_locale/codecvt/codecvt_utf8/69703.cc: New test.
    	* testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc: Test
    	that little_endian mode is ignored.
    	* testsuite/experimental/filesystem/path/native/string.cc: New test.

diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc
index 327beb6..b6b6358 100644
--- a/libstdc++-v3/src/c++11/codecvt.cc
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -789,7 +789,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
 {
   range<const char> from{ __from, __from_end };
   range<char16_t> to{ __to, __to_end };
-  auto res = ucs2_in(from, to, _M_maxcode, _M_mode);
+  codecvt_mode mode = codecvt_mode(_M_mode | (consume_header|generate_header));
+#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
+  mode = codecvt_mode(mode | little_endian);
+#endif
+  auto res = ucs2_in(from, to, _M_maxcode, mode);
   __from_next = from.next;
   __to_next = to.next;
   return res;
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/69703.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/69703.cc
new file mode 100644
index 0000000..745d2c2
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/69703.cc
@@ -0,0 +1,103 @@
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  const char out[] = "abc";
+  char16_t in[4];
+  std::codecvt_utf8<char16_t> cvt;
+  std::mbstate_t st;
+  const char* no;
+  char16_t* ni;
+  auto res = cvt.in(st, out, out+3, no, in, in+3, ni);
+  VERIFY( res == std::codecvt_base::ok );
+  VERIFY( in[0] == u'a' );
+  VERIFY( in[1] == u'b' );
+  VERIFY( in[2] == u'c' );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  const char out[] = "abc";
+  char16_t in[4];
+  std::codecvt_utf8<char16_t, 0x10ffff, std::little_endian> cvt;
+  std::mbstate_t st;
+  const char* no;
+  char16_t* ni;
+  auto res = cvt.in(st, out, out+3, no, in, in+3, ni);
+  VERIFY( res == std::codecvt_base::ok );
+  VERIFY( in[0] == u'a' );
+  VERIFY( in[1] == u'b' );
+  VERIFY( in[2] == u'c' );
+}
+
+void
+test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  const char out[] = "abc";
+  char32_t in[4];
+  std::codecvt_utf8<char32_t> cvt;
+  std::mbstate_t st;
+  const char* no;
+  char32_t* ni;
+  auto res = cvt.in(st, out, out+3, no, in, in+3, ni);
+  VERIFY( res == std::codecvt_base::ok );
+  VERIFY( in[0] == U'a' );
+  VERIFY( in[1] == U'b' );
+  VERIFY( in[2] == U'c' );
+}
+
+
+void
+test04()
+{
+  bool test __attribute__((unused)) = true;
+
+  const char out[] = "abc";
+  char32_t in[4];
+  std::codecvt_utf8<char32_t, 0x10ffff, std::little_endian> cvt;
+  std::mbstate_t st;
+  const char* no;
+  char32_t* ni;
+  auto res = cvt.in(st, out, out+3, no, in, in+3, ni);
+  VERIFY( res == std::codecvt_base::ok );
+  VERIFY( in[0] == U'a' );
+  VERIFY( in[1] == U'b' );
+  VERIFY( in[2] == U'c' );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc
index 05e5bc6..49b750f 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc
@@ -45,8 +45,35 @@ test01()
   VERIFY( buf[3] == utf16[3] );
 }
 
+void
+test02()
+{
+  // Endianness flag should make no difference.
+  std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::little_endian> cvt;
+  char16_t utf16[] = u"\ub098\ub294\ud0dc\uc624";
+  const char16_t* nf16;
+  char utf8[16];
+  char* nt8;
+  std::mbstate_t st{};
+  auto res = cvt.out(st, utf16, utf16+4, nf16, utf8, utf8+16, nt8);
+  VERIFY( res == std::codecvt_base::ok );
+
+  st = {};
+  char16_t buf[4] = {};
+  const char* nf8 = nt8;
+  char16_t* nt16;
+  res = cvt.in(st, utf8, nf8, nf8, buf, buf+4, nt16);
+  VERIFY( res == std::codecvt_base::ok );
+  VERIFY( nt16 == buf+4 );
+  VERIFY( buf[0] == utf16[0] );
+  VERIFY( buf[1] == utf16[1] );
+  VERIFY( buf[2] == utf16[2] );
+  VERIFY( buf[3] == utf16[3] );
+}
+
 int
 main()
 {
   test01();
+  test02();
 }
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
new file mode 100644
index 0000000..05ff57c
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 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/>.
+
+// { dg-options "-std=gnu++11 -lstdc++fs" }
+
+#include <experimental/filesystem>
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  using namespace std::experimental::filesystem;
+  const std::string s = "abc";
+  path p(s);
+
+  VERIFY( p.native() == s );
+  VERIFY( p.c_str() == s );
+  VERIFY( static_cast<std::string>(p) == s );
+
+  std::string s2 = p; // implicit conversion
+  VERIFY( s2 == p.native() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  using namespace std::experimental::filesystem;
+  const char* s = "abc";
+  path p(s);
+
+  auto str = p.string<char>();
+  VERIFY( str == u"abc" );
+  VERIFY( str == p.string() );
+
+  auto strw = p.string<wchar_t>();
+  VERIFY( strw == L"abc" );
+  VERIFY( strw == p.wstring() );
+
+  auto str16 = p.string<char16_t>();
+  VERIFY( str16 == u"abc" );
+  VERIFY( str16 == p.u16string() );
+
+  auto str32 = p.string<char32_t>();
+  VERIFY( str32 == U"abc" );
+  VERIFY( str32 == p.u32string() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [patch] Fix configure test for sendfile()
  2016-04-19 18:08   ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
@ 2016-04-19 18:31     ` Jonathan Wakely
  2016-05-25 18:38       ` Jonathan Wakely
  2016-04-20 17:40     ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
  1 sibling, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-04-19 18:31 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

One more fix for the Filesystem library: my configure test for the GNU
and Solaris version of sendfile was failing because it used NULL
without stddef.h, so we never used sendfile. That was useful, because
it meant someone found and reported a bug in the alternative
implementation that doesn't use sendfile, but it will be much faster
to use sendfile when available.

This fixes the configure test, but as it affects the build config I
won't commit it until after 6.1 is released.

Tested x86_64-linux.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1127 bytes --]

commit 867bf574bad0ba186d941520c2575e8be1ea5366
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Apr 19 19:17:50 2016 +0100

    Fix configure test for sendfile()
    
    	* acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Fix test for sendfile.
    	* configure: Regenerate.
    	* config.h.in: Regenerate.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b0f88cb..0824243 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4373,7 +4373,7 @@ dnl
       gnu* | linux* | solaris*)
         GCC_TRY_COMPILE_OR_LINK(
           [#include <sys/sendfile.h>],
-          [sendfile(1, 2, (off_t*)NULL, sizeof 1);],
+          [sendfile(1, 2, (off_t*)0, sizeof 1);],
           [glibcxx_cv_sendfile=yes],
           [glibcxx_cv_sendfile=no])
         ;;
@@ -4383,7 +4383,7 @@ dnl
     esac
   ])
   if test $glibcxx_cv_sendfile = yes; then
-    AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in <sys/stat.h>.])
+    AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in <sys/sendfile.h>.])
   fi
   AC_MSG_RESULT($glibcxx_cv_sendfile)
 dnl

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-04-19 18:08   ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
  2016-04-19 18:31     ` [patch] Fix configure test for sendfile() Jonathan Wakely
@ 2016-04-20 17:40     ` Jonathan Wakely
  2016-05-04 16:19       ` Andre Vieira (lists)
  1 sibling, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-04-20 17:40 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 359 bytes --]

On 19/04/16 19:07 +0100, Jonathan Wakely wrote:
>This was reported as a bug in the Filesystem library, but it's
>actually a problem in the codecvt_utf8 facet that it uses.

The fix had a silly typo meaning it didn't work for big endian
targets, which was revealed by the improved tests I added.

Tested x86_64-linux and powerpc64-linux, committed to trunk.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1446 bytes --]

commit 3a57afb171190fc8554d68094f9d4e3d2d0b2576
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 20 17:44:50 2016 +0100

    Fix std::codecvt_utf8* for big-endian targets
    
    	PR libstdc++/69703
    	* src/c++11/codecvt.cc (__codecvt_utf8_base<char16_t>::do_in,
    	__codecvt_utf8_utf16_base<char16_t>::do_in): Fix mask operations.

diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc
index b6b6358..b60691c 100644
--- a/libstdc++-v3/src/c++11/codecvt.cc
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -789,7 +789,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
 {
   range<const char> from{ __from, __from_end };
   range<char16_t> to{ __to, __to_end };
-  codecvt_mode mode = codecvt_mode(_M_mode | (consume_header|generate_header));
+  codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header));
 #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
   mode = codecvt_mode(mode | little_endian);
 #endif
@@ -1268,7 +1268,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
 {
   range<const char> from{ __from, __from_end };
   range<char16_t> to{ __to, __to_end };
-  codecvt_mode mode = codecvt_mode(_M_mode | (consume_header|generate_header));
+  codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header));
 #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
   mode = codecvt_mode(mode | little_endian);
 #endif

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-04-20 17:40     ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
@ 2016-05-04 16:19       ` Andre Vieira (lists)
  2016-05-05 10:12         ` Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Andre Vieira (lists) @ 2016-05-04 16:19 UTC (permalink / raw)
  To: jwakely; +Cc: gcc-patches

On 20/04/16 18:40, Jonathan Wakely wrote:
> On 19/04/16 19:07 +0100, Jonathan Wakely wrote:
>> This was reported as a bug in the Filesystem library, but it's
>> actually a problem in the codecvt_utf8 facet that it uses.
> 
> The fix had a silly typo meaning it didn't work for big endian
> targets, which was revealed by the improved tests I added.
> 
> Tested x86_64-linux and powerpc64-linux, committed to trunk.
> 
> 
Hi Jonathan,

We are seeing experimental/filesystem/path/native/string.cc fail on
baremetal targets. I'm guessing this is missing a
'dg-require-filesystem-ts', as seen on other tests like
experimental/filesystem/path/modifiers/swap.cc.

Cheers,
Andre

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-05-04 16:19       ` Andre Vieira (lists)
@ 2016-05-05 10:12         ` Jonathan Wakely
  2016-05-26 14:36           ` Christophe Lyon
  0 siblings, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-05-05 10:12 UTC (permalink / raw)
  To: Andre Vieira (lists); +Cc: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 800 bytes --]

On 04/05/16 17:19 +0100, Andre Vieira (lists) wrote:
>On 20/04/16 18:40, Jonathan Wakely wrote:
>> On 19/04/16 19:07 +0100, Jonathan Wakely wrote:
>>> This was reported as a bug in the Filesystem library, but it's
>>> actually a problem in the codecvt_utf8 facet that it uses.
>>
>> The fix had a silly typo meaning it didn't work for big endian
>> targets, which was revealed by the improved tests I added.
>>
>> Tested x86_64-linux and powerpc64-linux, committed to trunk.
>>
>>
>Hi Jonathan,
>
>We are seeing experimental/filesystem/path/native/string.cc fail on
>baremetal targets. I'm guessing this is missing a
>'dg-require-filesystem-ts', as seen on other tests like
>experimental/filesystem/path/modifiers/swap.cc.
>
>Cheers,
>Andre

Sorry about that, I've committed the missing directive.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 825 bytes --]

commit 775381d7e53d5a68a2725b6b72f081d254d9380b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 5 10:42:35 2016 +0100

    Add dg-require-filesystem-ts directive to test
    
    	* testsuite/experimental/filesystem/path/native/string.cc: Add
    	dg-require-filesystem-ts directive.

diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
index 05ff57c..e56fda7 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
@@ -16,6 +16,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-options "-std=gnu++11 -lstdc++fs" }
+// { dg-require-filesystem-ts "" }
 
 #include <experimental/filesystem>
 #include <string>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] Fix configure test for sendfile()
  2016-04-19 18:31     ` [patch] Fix configure test for sendfile() Jonathan Wakely
@ 2016-05-25 18:38       ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-05-25 18:38 UTC (permalink / raw)
  To: libstdc++, gcc-patches

On 19/04/16 19:30 +0100, Jonathan Wakely wrote:
>One more fix for the Filesystem library: my configure test for the GNU
>and Solaris version of sendfile was failing because it used NULL
>without stddef.h, so we never used sendfile. That was useful, because
>it meant someone found and reported a bug in the alternative
>implementation that doesn't use sendfile, but it will be much faster
>to use sendfile when available.
>
>This fixes the configure test, but as it affects the build config I
>won't commit it until after 6.1 is released.

Committed to trunk.


>Tested x86_64-linux.
>

>commit 867bf574bad0ba186d941520c2575e8be1ea5366
>Author: Jonathan Wakely <jwakely@redhat.com>
>Date:   Tue Apr 19 19:17:50 2016 +0100
>
>    Fix configure test for sendfile()
>    
>    	* acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Fix test for sendfile.
>    	* configure: Regenerate.
>    	* config.h.in: Regenerate.
>
>diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
>index b0f88cb..0824243 100644
>--- a/libstdc++-v3/acinclude.m4
>+++ b/libstdc++-v3/acinclude.m4
>@@ -4373,7 +4373,7 @@ dnl
>       gnu* | linux* | solaris*)
>         GCC_TRY_COMPILE_OR_LINK(
>           [#include <sys/sendfile.h>],
>-          [sendfile(1, 2, (off_t*)NULL, sizeof 1);],
>+          [sendfile(1, 2, (off_t*)0, sizeof 1);],
>           [glibcxx_cv_sendfile=yes],
>           [glibcxx_cv_sendfile=no])
>         ;;
>@@ -4383,7 +4383,7 @@ dnl
>     esac
>   ])
>   if test $glibcxx_cv_sendfile = yes; then
>-    AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in <sys/stat.h>.])
>+    AC_DEFINE(_GLIBCXX_USE_SENDFILE, 1, [Define if sendfile is available in <sys/sendfile.h>.])
>   fi
>   AC_MSG_RESULT($glibcxx_cv_sendfile)
> dnl

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-05-05 10:12         ` Jonathan Wakely
@ 2016-05-26 14:36           ` Christophe Lyon
  2016-05-26 14:36             ` Christophe Lyon
  0 siblings, 1 reply; 11+ messages in thread
From: Christophe Lyon @ 2016-05-26 14:36 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Andre Vieira (lists), gcc-patches, libstdc++

On 5 May 2016 at 12:12, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 04/05/16 17:19 +0100, Andre Vieira (lists) wrote:
>>
>> On 20/04/16 18:40, Jonathan Wakely wrote:
>>>
>>> On 19/04/16 19:07 +0100, Jonathan Wakely wrote:
>>>>
>>>> This was reported as a bug in the Filesystem library, but it's
>>>> actually a problem in the codecvt_utf8 facet that it uses.
>>>
>>>
>>> The fix had a silly typo meaning it didn't work for big endian
>>> targets, which was revealed by the improved tests I added.
>>>
>>> Tested x86_64-linux and powerpc64-linux, committed to trunk.
>>>
>>>
>> Hi Jonathan,
>>
>> We are seeing experimental/filesystem/path/native/string.cc fail on
>> baremetal targets. I'm guessing this is missing a
>> 'dg-require-filesystem-ts', as seen on other tests like
>> experimental/filesystem/path/modifiers/swap.cc.
>>
>> Cheers,
>> Andre
>
>
> Sorry about that, I've committed the missing directive.
>
>
Hi,

I've seen you've backported the main patch to the gcc-6 branch, you
forgot to add the follow-up "Add dg-require-filesystem-ts directive to
test".

Christophe

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-05-26 14:36           ` Christophe Lyon
@ 2016-05-26 14:36             ` Christophe Lyon
  2016-05-26 17:12               ` Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Christophe Lyon @ 2016-05-26 14:36 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Andre Vieira (lists), gcc-patches, libstdc++

On 26 May 2016 at 13:58, Christophe Lyon <christophe.lyon@linaro.org> wrote:
> On 5 May 2016 at 12:12, Jonathan Wakely <jwakely@redhat.com> wrote:
>> On 04/05/16 17:19 +0100, Andre Vieira (lists) wrote:
>>>
>>> On 20/04/16 18:40, Jonathan Wakely wrote:
>>>>
>>>> On 19/04/16 19:07 +0100, Jonathan Wakely wrote:
>>>>>
>>>>> This was reported as a bug in the Filesystem library, but it's
>>>>> actually a problem in the codecvt_utf8 facet that it uses.
>>>>
>>>>
>>>> The fix had a silly typo meaning it didn't work for big endian
>>>> targets, which was revealed by the improved tests I added.
>>>>
>>>> Tested x86_64-linux and powerpc64-linux, committed to trunk.
>>>>
>>>>
>>> Hi Jonathan,
>>>
>>> We are seeing experimental/filesystem/path/native/string.cc fail on
>>> baremetal targets. I'm guessing this is missing a
>>> 'dg-require-filesystem-ts', as seen on other tests like
>>> experimental/filesystem/path/modifiers/swap.cc.
>>>
>>> Cheers,
>>> Andre
>>
>>
>> Sorry about that, I've committed the missing directive.
>>
>>
> Hi,
>
> I've seen you've backported the main patch to the gcc-6 branch, you
> forgot to add the follow-up "Add dg-require-filesystem-ts directive to
> test".
>
And likewise for the gcc-5 branch.

> Christophe

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] libstdc++/69703 ignore endianness in codecvt_utf8
  2016-05-26 14:36             ` Christophe Lyon
@ 2016-05-26 17:12               ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-05-26 17:12 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Andre Vieira (lists), gcc-patches, libstdc++

On 26/05/16 14:02 +0200, Christophe Lyon wrote:
>> I've seen you've backported the main patch to the gcc-6 branch, you
>> forgot to add the follow-up "Add dg-require-filesystem-ts directive to
>> test".
>>
>And likewise for the gcc-5 branch.

Both fixed now, sorry about that, again.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-05-26 15:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-19 18:03 [patch] Add noexcept to Filesystem TS operators Jonathan Wakely
2016-04-19 18:06 ` [patch] libstdc++/70609 fix filesystem::copy() Jonathan Wakely
2016-04-19 18:08   ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
2016-04-19 18:31     ` [patch] Fix configure test for sendfile() Jonathan Wakely
2016-05-25 18:38       ` Jonathan Wakely
2016-04-20 17:40     ` [patch] libstdc++/69703 ignore endianness in codecvt_utf8 Jonathan Wakely
2016-05-04 16:19       ` Andre Vieira (lists)
2016-05-05 10:12         ` Jonathan Wakely
2016-05-26 14:36           ` Christophe Lyon
2016-05-26 14:36             ` Christophe Lyon
2016-05-26 17:12               ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).