[gcc-6] 315/401: * Update to SVN 20161212 (r243558, 6.2.1) from the gcc-6-branch.

Ximin Luo infinity0 at debian.org
Wed Apr 5 15:50:21 UTC 2017


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch pu/reproducible_builds
in repository gcc-6.

commit ae978f065225a2d60abf40d4c873e333c28e03e6
Author: doko <doko at 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca>
Date:   Mon Dec 12 16:05:20 2016 +0000

      * Update to SVN 20161212 (r243558, 6.2.1) from the gcc-6-branch.
    
    
    git-svn-id: svn://anonscm.debian.org/gcccvs/branches/sid/gcc-6@9178 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca
---
 debian/changelog                |    8 +-
 debian/control                  |    2 +-
 debian/patches/svn-updates.diff | 2638 ++++++++++++++++++++++++++++++++++++++-
 debian/rules.conf               |    4 +-
 4 files changed, 2624 insertions(+), 28 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 96f177b..aeb2f5e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,6 @@
 gcc-6 (6.2.1-6) UNRELEASED; urgency=medium
 
-  * Update to SVN 20161212 (r243541, 6.2.1) from the gcc-6-branch.
+  * Update to SVN 20161212 (r243558, 6.2.1) from the gcc-6-branch.
     - Fix PR target/78426 (SH), PR fortran/78500, PR target/78101 (PPC),
       PR target/48863 (ARM32), PR inline-asm/70184, PR libstdc++/71856,
       PR libstdc++/77459, PR libstdc++/78326, PR libstdc++/51960,
@@ -19,7 +19,9 @@ gcc-6 (6.2.1-6) UNRELEASED; urgency=medium
       PR c++/77739, PR c++/77285, PR c++/78089, PR c++/77467, PR c++/77722,
       PR c++/77638, PR c++/77637, PR c++/77482, PR c++/77375, PR c++/71274,
       PR c++/71515, PR c++/77907, PR c++/57728, PR fortran/78593,
-      PR fortran/77666, PR fortran/78443.
+      PR fortran/77666, PR fortran/78443, PR libstdc++/70975,
+      PR libstdc++/71337, PR libstdc++/78111, PR rtl-optimization/77309,
+      PR target/77904 (ARM32).
 
   [ Matthias Klose ]
   * Fix dependency generation for libgphobos multilib builds.
@@ -39,7 +41,7 @@ gcc-6 (6.2.1-6) UNRELEASED; urgency=medium
   * Use needsCodegen rather than isRoot for determining the static/extern of a
     template symbol. Closes: #845377.
 
- -- Matthias Klose <doko at debian.org>  Mon, 12 Dec 2016 11:38:52 +0100
+ -- Matthias Klose <doko at debian.org>  Mon, 12 Dec 2016 16:53:57 +0100
 
 gcc-6 (6.2.1-5) unstable; urgency=medium
 
diff --git a/debian/control b/debian/control
index 6bee9c0..c1a0961 100644
--- a/debian/control
+++ b/debian/control
@@ -12,7 +12,7 @@ Build-Depends: debhelper (>= 9.20141010), dpkg-dev (>= 1.17.14),
   libunwind7-dev (>= 0.98.5-6) [ia64], libatomic-ops-dev [ia64], 
   autogen, gawk, lzma, xz-utils, patchutils, 
   zlib1g-dev, systemtap-sdt-dev [linux-any kfreebsd-any hurd-any], 
-  binutils:native (>= 2.27.51.20161124-1) | binutils-multiarch:native (>= 2.27.51.20161124-1), binutils-hppa64-linux-gnu:native (>= 2.27.51.20161124-1) [hppa amd64 i386 x32], 
+  binutils:native (>= 2.27.51.20161212) | binutils-multiarch:native (>= 2.27.51.20161212), binutils-hppa64-linux-gnu:native (>= 2.27.51.20161212) [hppa amd64 i386 x32], 
   gperf (>= 3.0.1), bison (>= 1:2.3), flex, gettext, 
   gdb:native, 
   texinfo (>= 4.3), locales, sharutils, 
diff --git a/debian/patches/svn-updates.diff b/debian/patches/svn-updates.diff
index c86c4b4..7c5b52e 100644
--- a/debian/patches/svn-updates.diff
+++ b/debian/patches/svn-updates.diff
@@ -1,10 +1,10 @@
-# DP: updates from the 6 branch upto 20161212 (r243541).
+# DP: updates from the 6 branch upto 20161212 (r243558).
 
 last_update()
 {
 	cat > ${dir}LAST_UPDATED <EOF
-Mon Dec 12 11:03:18 CET 2016
-Mon Dec 12 10:03:18 UTC 2016 (revision 243541)
+Mon Dec 12 16:48:37 CET 2016
+Mon Dec 12 15:48:37 UTC 2016 (revision 243558)
 EOF
 }
 
@@ -541,6 +541,579 @@ Index: libstdc++-v3/scripts/testsuite_flags.in
        CXXFLAGS_config="@SECTION_FLAGS@ @EXTRA_CXX_FLAGS@"
        echo ${CXXFLAGS_default} ${CXXFLAGS_config} 
        ;;
+Index: libstdc++-v3/src/filesystem/dir.cc
+===================================================================
+--- a/src/libstdc++-v3/src/filesystem/dir.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/src/filesystem/dir.cc	(.../branches/gcc-6-branch)
+@@ -79,8 +79,7 @@
+       return (obj & bits) != Bitmask::none;
+     }
+ 
+-  // Returns {dirp, p} on success, {nullptr, p} on error.
+-  // If an ignored EACCES error occurs returns {}.
++  // Returns {dirp, p} on success, {} on error (whether ignored or not).
+   inline fs::_Dir
+   open_dir(const fs::path& p, fs::directory_options options,
+ 	   std::error_code* ec)
+@@ -102,7 +101,7 @@
+             std::error_code(err, std::generic_category())));
+ 
+     ec->assign(err, std::generic_category());
+-    return {nullptr, p};
++    return {};
+   }
+ 
+   inline fs::file_type
+@@ -169,7 +168,7 @@
+ 	      "directory iterator cannot advance",
+ 	      std::error_code(err, std::generic_category())));
+       ec->assign(err, std::generic_category());
+-      return true;
++      return false;
+     }
+   else
+     {
+@@ -191,12 +190,6 @@
+       if (sp->advance(ec, options))
+ 	_M_dir.swap(sp);
+     }
+-  else if (!dir.path.empty())
+-    {
+-      // An error occurred, we need a non-empty shared_ptr so that *this will
+-      // not compare equal to the end iterator.
+-      _M_dir.reset(static_cast<fs::_Dir*>(nullptr));
+-    }
+ }
+ 
+ const fs::directory_entry&
+@@ -270,10 +263,6 @@
+ 	      std::error_code(err, std::generic_category())));
+ 
+       ec->assign(err, std::generic_category());
+-
+-      // An error occurred, we need a non-empty shared_ptr so that *this will
+-      // not compare equal to the end iterator.
+-      _M_dirs.reset(static_cast<_Dir_stack*>(nullptr));
+     }
+ }
+ 
+@@ -354,7 +343,10 @@
+     {
+       _Dir dir = open_dir(top.entry.path(), _M_options, &ec);
+       if (ec)
+-	return *this;
++	{
++	  _M_dirs.reset();
++	  return *this;
++	}
+       if (dir.dirp)
+ 	  _M_dirs->push(std::move(dir));
+     }
+@@ -372,12 +364,13 @@
+ }
+ 
+ void
+-fs::recursive_directory_iterator::pop()
++fs::recursive_directory_iterator::pop(error_code& ec)
+ {
+   if (!_M_dirs)
+-    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+-	  "cannot pop non-dereferenceable recursive directory iterator",
+-	  std::make_error_code(errc::invalid_argument)));
++    {
++      ec = std::make_error_code(errc::invalid_argument);
++      return;
++    }
+ 
+   do {
+     _M_dirs->pop();
+@@ -384,7 +377,20 @@
+     if (_M_dirs->empty())
+       {
+ 	_M_dirs.reset();
++	ec.clear();
+ 	return;
+       }
+-  } while (!_M_dirs->top().advance(nullptr, _M_options));
++  } while (!_M_dirs->top().advance(&ec, _M_options));
+ }
++
++void
++fs::recursive_directory_iterator::pop()
++{
++  error_code ec;
++  pop(ec);
++  if (ec)
++    _GLIBCXX_THROW_OR_ABORT(filesystem_error(_M_dirs
++	  ? "recursive directory iterator cannot pop"
++	  : "non-dereferenceable recursive directory iterator cannot pop",
++	  ec));
++}
+Index: libstdc++-v3/src/filesystem/ops.cc
+===================================================================
+--- a/src/libstdc++-v3/src/filesystem/ops.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/src/filesystem/ops.cc	(.../branches/gcc-6-branch)
+@@ -28,7 +28,9 @@
+ 
+ #include <experimental/filesystem>
+ #include <functional>
++#include <ostream>
+ #include <stack>
++#include <ext/stdio_filebuf.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <errno.h>
+@@ -48,9 +50,6 @@
+ #endif
+ #ifdef _GLIBCXX_USE_SENDFILE
+ # include <sys/sendfile.h>
+-#else
+-# include <ext/stdio_filebuf.h>
+-# include <ostream>
+ #endif
+ #if _GLIBCXX_HAVE_UTIME_H
+ # include <utime.h>
+@@ -143,7 +142,11 @@
+ #endif
+ 
+   if (!exists(pa, ec))
+-    return result;
++    {
++      if (!ec)
++	ec = make_error_code(std::errc::no_such_file_or_directory);
++      return result;
++    }
+   // else: we know there are (currently) no unresolvable symlink loops
+ 
+   result = pa.root_path();
+@@ -289,27 +292,24 @@
+   }
+ 
+   inline fs::file_time_type
+-  file_time(const stat_type& st) noexcept
++  file_time(const stat_type& st, std::error_code& ec) noexcept
+   {
+     using namespace std::chrono;
+-    return fs::file_time_type{
+ #ifdef _GLIBCXX_USE_ST_MTIM
+-	seconds{st.st_mtim.tv_sec} + nanoseconds{st.st_mtim.tv_nsec}
++    time_t s = st.st_mtim.tv_sec;
++    nanoseconds ns{st.st_mtim.tv_nsec};
+ #else
+-	seconds{st.st_mtime}
++    time_t s = st.st_mtime;
++    nanoseconds ns{};
+ #endif
+-    };
+-  }
+ 
+-  // 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;
++    if (s >= (nanoseconds::max().count() / 1e9))
++      {
++	ec = std::make_error_code(std::errc::value_too_large); // EOVERFLOW
++	return fs::file_time_type::min();
++      }
++    ec.clear();
++    return fs::file_time_type{seconds{s} + ns};
+   }
+ 
+   bool
+@@ -354,13 +354,25 @@
+ 	  from_st = &st2;
+       }
+     f = make_file_status(*from_st);
++    // _GLIBCXX_RESOLVE_LIB_DEFECTS
++    // 2712. copy_file() has a number of unspecified error conditions
++    if (!is_regular_file(f))
++      {
++	ec = std::make_error_code(std::errc::not_supported);
++	return false;
++      }
+ 
+     using opts = fs::copy_options;
+ 
+     if (exists(t))
+       {
+-	if (!is_other(t) && !is_other(f)
+-	    && to_st->st_dev == from_st->st_dev
++	if (!is_regular_file(t))
++	  {
++	    ec = std::make_error_code(std::errc::not_supported);
++	    return false;
++	  }
++
++	if (to_st->st_dev == from_st->st_dev
+ 	    && to_st->st_ino == from_st->st_ino)
+ 	  {
+ 	    ec = std::make_error_code(std::errc::file_exists);
+@@ -374,11 +386,11 @@
+ 	  }
+ 	else if (is_set(option, opts::update_existing))
+ 	  {
+-	    if (file_time(*from_st) <= file_time(*to_st))
+-	      {
+-		ec.clear();
+-		return false;
+-	      }
++	    const auto from_mtime = file_time(*from_st, ec);
++	    if (ec)
++	      return false;
++	    if ((from_mtime <= file_time(*to_st, ec)) || ec)
++	      return false;
+ 	  }
+ 	else if (!is_set(option, opts::overwrite_existing))
+ 	  {
+@@ -385,11 +397,16 @@
+ 	    ec = std::make_error_code(std::errc::file_exists);
+ 	    return false;
+ 	  }
++	else if (!is_regular_file(t))
++	  {
++	    ec = std::make_error_code(std::errc::not_supported);
++	    return false;
++	  }
+       }
+ 
+     struct CloseFD {
+-      ~CloseFD() { if (fd != -1) close_fd(fd); }
+-      bool close() { return close_fd(std::exchange(fd, -1)); }
++      ~CloseFD() { if (fd != -1) ::close(fd); }
++      bool close() { return ::close(std::exchange(fd, -1)) == 0; }
+       int fd;
+     };
+ 
+@@ -416,7 +433,7 @@
+ 
+ #ifdef _GLIBCXX_USE_FCHMOD
+     if (::fchmod(out.fd, from_st->st_mode))
+-#elif _GLIBCXX_USE_FCHMODAT
++#elif defined _GLIBCXX_USE_FCHMODAT
+     if (::fchmodat(AT_FDCWD, to.c_str(), from_st->st_mode, 0))
+ #else
+     if (::chmod(to.c_str(), from_st->st_mode))
+@@ -427,7 +444,33 @@
+       }
+ 
+ #ifdef _GLIBCXX_USE_SENDFILE
+-    const auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size);
++    off_t offset = 0;
++    const auto n = ::sendfile(out.fd, in.fd, &offset, from_st->st_size);
++    if (n < 0 && (errno == ENOSYS || errno == EINVAL))
++      {
++#endif
++	__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;
++	  }
++
++	ec.clear();
++	return true;
++
++#ifdef _GLIBCXX_USE_SENDFILE
++      }
+     if (n != from_st->st_size)
+       {
+ 	ec.assign(errno, std::generic_category());
+@@ -438,27 +481,10 @@
+ 	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;
++#endif
+   }
+ }
+ #endif
+@@ -474,7 +500,8 @@
+ 
+   file_status f, t;
+   stat_type from_st, to_st;
+-  // N4099 doesn't check copy_symlinks here, but I think that's a defect.
++  // _GLIBCXX_RESOLVE_LIB_DEFECTS
++  // 2681. filesystem::copy() cannot copy symlinks
+   if (use_lstat || copy_symlinks
+       ? ::lstat(from.c_str(), &from_st)
+       : ::stat(from.c_str(), &from_st))
+@@ -541,6 +568,10 @@
+ 	  do_copy_file(from, to, options, &from_st, ptr,  ec);
+ 	}
+     }
++  // _GLIBCXX_RESOLVE_LIB_DEFECTS
++  // 2682. filesystem::copy() won't create a symlink to a directory
++  else if (is_directory(f) && create_symlinks)
++    ec = std::make_error_code(errc::is_a_directory);
+   else if (is_directory(f) && (is_set(options, copy_options::recursive)
+ 			       || options == copy_options::none))
+     {
+@@ -553,7 +584,10 @@
+       for (const directory_entry& x : directory_iterator(from))
+ 	copy(x.path(), to/x.path().filename(), options, ec);
+     }
+-  // "Otherwise no effects." (should ec.clear() be called?)
++  // _GLIBCXX_RESOLVE_LIB_DEFECTS
++  // 2683. filesystem::copy() says "no effects"
++  else
++    ec.clear();
+ }
+ 
+ bool
+@@ -890,7 +924,7 @@
+ {
+   error_code ec;
+   auto result = equivalent(p1, p2, ec);
+-  if (ec.value())
++  if (ec)
+     _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot check file equivalence",
+ 	  p1, p2, ec));
+   return result;
+@@ -900,11 +934,25 @@
+ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept
+ {
+ #ifdef _GLIBCXX_HAVE_SYS_STAT_H
++  int err = 0;
++  file_status s1, s2;
+   stat_type st1, st2;
+-  if (::stat(p1.c_str(), &st1) == 0 && ::stat(p2.c_str(), &st2) == 0)
++  if (::stat(p1.c_str(), &st1) == 0)
++    s1 = make_file_status(st1);
++  else if (is_not_found_errno(errno))
++    s1.type(file_type::not_found);
++  else
++    err = errno;
++
++  if (::stat(p2.c_str(), &st2) == 0)
++    s2 = make_file_status(st2);
++  else if (is_not_found_errno(errno))
++    s2.type(file_type::not_found);
++  else
++    err = errno;
++
++  if (exists(s1) && exists(s2))
+     {
+-      file_status s1 = make_file_status(st1);
+-      file_status s2 = make_file_status(st2);
+       if (is_other(s1) && is_other(s2))
+ 	{
+ 	  ec = std::make_error_code(std::errc::not_supported);
+@@ -911,14 +959,17 @@
+ 	  return false;
+ 	}
+       ec.clear();
++      if (is_other(s1) || is_other(s2))
++	return false;
+       return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino;
+     }
+-  else if (is_not_found_errno(errno))
+-    {
+-      ec = std::make_error_code(std::errc::no_such_file_or_directory);
+-      return false;
+-    }
+-  ec.assign(errno, std::generic_category());
++  else if (!exists(s1) && !exists(s2))
++    ec = std::make_error_code(std::errc::no_such_file_or_directory);
++  else if (err)
++    ec.assign(err, std::generic_category());
++  else
++    ec.clear();
++  return false;
+ #else
+   ec = std::make_error_code(std::errc::not_supported);
+ #endif
+@@ -1000,9 +1051,12 @@
+ bool
+ fs::is_empty(const path& p)
+ {
+-  return fs::is_directory(status(p))
+-    ? fs::directory_iterator(p) == fs::directory_iterator()
+-    : fs::file_size(p) == 0;
++  error_code ec;
++  bool e = is_empty(p, ec);
++  if (ec)
++    _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot check if file is empty",
++					     p, ec));
++  return e;
+ }
+ 
+ bool
+@@ -1009,11 +1063,12 @@
+ fs::is_empty(const path& p, error_code& ec) noexcept
+ {
+   auto s = status(p, ec);
+-  if (ec.value())
++  if (ec)
+     return false;
+-  return fs::is_directory(s)
++  bool empty = fs::is_directory(s)
+     ? fs::directory_iterator(p, ec) == fs::directory_iterator()
+     : fs::file_size(p, ec) == 0;
++  return ec ? false : empty;
+ }
+ 
+ fs::file_time_type
+@@ -1029,7 +1084,7 @@
+ fs::file_time_type
+ fs::last_write_time(const path& p, error_code& ec) noexcept
+ {
+-  return do_stat(p, ec, [](const auto& st) { return file_time(st); },
++  return do_stat(p, ec, [&ec](const auto& st) { return file_time(st, ec); },
+ 		 file_time_type::min());
+ }
+ 
+@@ -1050,6 +1105,11 @@
+   auto s = chrono::duration_cast<chrono::seconds>(d);
+ #if _GLIBCXX_USE_UTIMENSAT
+   auto ns = chrono::duration_cast<chrono::nanoseconds>(d - s);
++  if (ns < ns.zero()) // tv_nsec must be non-negative and less than 10e9.
++    {
++      --s;
++      ns += chrono::seconds(1);
++    }
+   struct ::timespec ts[2];
+   ts[0].tv_sec = 0;
+   ts[0].tv_nsec = UTIME_OMIT;
+@@ -1082,10 +1142,12 @@
+     _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot set permissions", p, ec));
+ }
+ 
+-void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
++void
++fs::permissions(const path& p, perms prms, error_code& ec) noexcept
+ {
+   const bool add = is_set(prms, perms::add_perms);
+   const bool remove = is_set(prms, perms::remove_perms);
++  const bool nofollow = is_set(prms, perms::symlink_nofollow);
+   if (add && remove)
+     {
+       ec = std::make_error_code(std::errc::invalid_argument);
+@@ -1094,24 +1156,33 @@
+ 
+   prms &= perms::mask;
+ 
+-  if (add || remove)
++  file_status st;
++  if (add || remove || nofollow)
+     {
+-      auto st = status(p, ec);
++      st = nofollow ? symlink_status(p, ec) : status(p, ec);
+       if (ec)
+ 	return;
+       auto curr = st.permissions();
+       if (add)
+ 	prms |= curr;
+-      else
++      else if (remove)
+ 	prms = curr & ~prms;
+     }
+ 
++  int err = 0;
+ #if _GLIBCXX_USE_FCHMODAT
+-  if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0))
++  const int flag = (nofollow && is_symlink(st)) ? AT_SYMLINK_NOFOLLOW : 0;
++  if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), flag))
++    err = errno;
+ #else
+-  if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
++  if (nofollow && is_symlink(st))
++    ec = std::make_error_code(std::errc::operation_not_supported);
++  else if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
++    err = errno;
+ #endif
+-    ec.assign(errno, std::generic_category());
++
++  if (err)
++    ec.assign(err, std::generic_category());
+   else
+     ec.clear();
+ }
+@@ -1142,6 +1213,7 @@
+       ec.assign(errno, std::generic_category());
+       return {};
+     }
++  ec.clear();
+   return path{buf.data(), buf.data()+len};
+ #else
+   ec = std::make_error_code(std::errc::not_supported);
+@@ -1282,7 +1354,7 @@
+ 
+ #ifdef _GLIBCXX_HAVE_SYS_STAT_H
+ fs::file_status
+-fs::status(const fs::path& p, std::error_code& ec) noexcept
++fs::status(const fs::path& p, error_code& ec) noexcept
+ {
+   file_status status;
+   stat_type st;
+@@ -1292,6 +1364,10 @@
+       ec.assign(err, std::generic_category());
+       if (is_not_found_errno(err))
+ 	status.type(file_type::not_found);
++#ifdef EOVERFLOW
++      else if (err == EOVERFLOW)
++	status.type(file_type::unknown);
++#endif
+     }
+   else
+     {
+@@ -1390,12 +1466,17 @@
+   for (auto e = env; tmpdir == nullptr && *e != nullptr; ++e)
+     tmpdir = ::getenv(*e);
+   path p = tmpdir ? tmpdir : "/tmp";
+-  if (exists(p) && is_directory(p))
++  auto st = status(p, ec);
++  if (!ec)
+     {
+-      ec.clear();
+-      return p;
++      if (is_directory(st))
++	{
++	  ec.clear();
++	  return p;
++	}
++      else
++	ec = std::make_error_code(std::errc::not_a_directory);
+     }
+-  ec = std::make_error_code(std::errc::not_a_directory);
+   return {};
+ #endif
+ }
 Index: libstdc++-v3/src/c++11/shared_ptr.cc
 ===================================================================
 --- a/src/libstdc++-v3/src/c++11/shared_ptr.cc	(.../tags/gcc_6_2_0_release)
@@ -2578,6 +3151,44 @@ Index: libstdc++-v3/include/experimental/string_view
  } // namespace experimental
  } // namespace std
  
+Index: libstdc++-v3/include/experimental/bits/fs_ops.h
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/bits/fs_ops.h	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/include/experimental/bits/fs_ops.h	(.../branches/gcc-6-branch)
+@@ -112,6 +112,12 @@
+   void current_path(const path& __p);
+   void current_path(const path& __p, error_code& __ec) noexcept;
+ 
++  bool
++  equivalent(const path& __p1, const path& __p2);
++
++  bool
++  equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept;
++
+   inline bool
+   exists(file_status __s) noexcept
+   { return status_known(__s) && __s.type() != file_type::not_found; }
+@@ -122,14 +128,13 @@
+ 
+   inline bool
+   exists(const path& __p, error_code& __ec) noexcept
+-  { return exists(status(__p, __ec)); }
++  {
++    auto __s = status(__p, __ec);
++    if (status_known(__s))
++      __ec.clear();
++    return exists(__s);
++  }
+ 
+-  bool
+-  equivalent(const path& __p1, const path& __p2);
+-
+-  bool
+-  equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept;
+-
+   uintmax_t file_size(const path& __p);
+   uintmax_t file_size(const path& __p, error_code& __ec) noexcept;
+ 
 Index: libstdc++-v3/include/experimental/bits/shared_ptr.h
 ===================================================================
 --- a/src/libstdc++-v3/include/experimental/bits/shared_ptr.h	(.../tags/gcc_6_2_0_release)
@@ -3516,6 +4127,197 @@ Index: libstdc++-v3/include/experimental/bits/string_view.tcc
  } // namespace experimental
  } // namespace std
  
+Index: libstdc++-v3/include/experimental/bits/fs_path.h
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/bits/fs_path.h	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/include/experimental/bits/fs_path.h	(.../branches/gcc-6-branch)
+@@ -44,6 +44,9 @@
+ #include <bits/stl_algobase.h>
+ #include <bits/quoted_string.h>
+ #include <bits/locale_conv.h>
++#if __cplusplus >= 201402L
++# include <experimental/string_view>
++#endif
+ 
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1
+@@ -61,6 +64,12 @@
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ _GLIBCXX_BEGIN_NAMESPACE_CXX11
+ 
++#if __cplusplus >= 201402L
++  template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
++    using __basic_string_view
++      = std::experimental::basic_string_view<_CharT, _Traits>;
++#endif
++
+   /**
+    * @ingroup filesystem
+    * @{
+@@ -87,6 +96,12 @@
+       static __is_encoded_char<_CharT>
+       __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
+ 
++#if __cplusplus >= 201402L
++    template<typename _CharT, typename _Traits>
++      static __is_encoded_char<_CharT>
++      __is_path_src(const __basic_string_view<_CharT, _Traits>&, int);
++#endif
++
+     template<typename _Unknown>
+       static std::false_type
+       __is_path_src(const _Unknown&, ...);
+@@ -130,6 +145,18 @@
+       _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str)
+       { return __str.data() + __str.size(); }
+ 
++#if __cplusplus >= 201402L
++    template<typename _CharT, typename _Traits>
++      static const _CharT*
++      _S_range_begin(const __basic_string_view<_CharT, _Traits>& __str)
++      { return __str.data(); }
++
++    template<typename _CharT, typename _Traits>
++      static const _CharT*
++      _S_range_end(const __basic_string_view<_CharT, _Traits>& __str)
++      { return __str.data() + __str.size(); }
++#endif
++
+     template<typename _Tp,
+ 	     typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())),
+ 	     typename _Val = typename std::iterator_traits<_Iter>::value_type>
+@@ -159,6 +186,10 @@
+       __p.clear();
+     }
+ 
++    path(string_type&& __source)
++    : _M_pathname(std::move(__source))
++    { _M_split_cmpts(); }
++
+     template<typename _Source,
+ 	     typename _Require = _Path<_Source>>
+       path(_Source const& __source)
+@@ -193,6 +224,8 @@
+ 
+     path& operator=(const path& __p) = default;
+     path& operator=(path&& __p) noexcept;
++    path& operator=(string_type&& __source);
++    path& assign(string_type&& __source);
+ 
+     template<typename _Source>
+       _Path<_Source>&
+@@ -237,6 +270,9 @@
+     path& operator+=(const string_type& __x);
+     path& operator+=(const value_type* __x);
+     path& operator+=(value_type __x);
++#if __cplusplus >= 201402L
++    path& operator+=(__basic_string_view<value_type> __x);
++#endif
+ 
+     template<typename _Source>
+       _Path<_Source>&
+@@ -305,6 +341,9 @@
+     int compare(const path& __p) const noexcept;
+     int compare(const string_type& __s) const;
+     int compare(const value_type* __s) const;
++#if __cplusplus >= 201402L
++    int compare(const __basic_string_view<value_type> __s) const;
++#endif
+ 
+     // decomposition
+ 
+@@ -379,7 +418,8 @@
+       _S_convert(_Iter __first, _Iter __last)
+       {
+ 	using __value_type = typename std::iterator_traits<_Iter>::value_type;
+-	return _Cvt<__value_type>::_S_convert(__first, __last);
++	return _Cvt<typename remove_cv<__value_type>::type>::
++	  _S_convert(__first, __last);
+       }
+ 
+     template<typename _InputIterator>
+@@ -387,10 +427,10 @@
+       _S_convert(_InputIterator __src, __null_terminated)
+       {
+ 	using _Tp = typename std::iterator_traits<_InputIterator>::value_type;
+-	std::basic_string<_Tp> __tmp;
+-	while (*__src != _Tp{})
+-	  __tmp.push_back(*__src++);
+-	return _S_convert(__tmp.data(), __tmp.data() + __tmp.size());
++	std::basic_string<typename remove_cv<_Tp>::type> __tmp;
++	for (; *__src != _Tp{}; ++__src)
++	  __tmp.push_back(*__src);
++	return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size());
+       }
+ 
+     static string_type
+@@ -565,6 +605,9 @@
+     struct path::__is_encoded_char<char32_t> : std::true_type
+     { using value_type = char32_t; };
+ 
++  template<typename _Tp>
++    struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { };
++
+   struct path::_Cmpt : path
+   {
+     _Cmpt(string_type __s, _Type __t, size_t __pos)
+@@ -722,6 +765,14 @@
+   }
+ 
+   inline path&
++  path::operator=(string_type&& __source)
++  { return *this = path(std::move(__source)); }
++
++  inline path&
++  path::assign(string_type&& __source)
++  { return *this = path(std::move(__source)); }
++
++  inline path&
+   path::operator+=(const path& __p)
+   {
+     return operator+=(__p.native());
+@@ -751,6 +802,16 @@
+     return *this;
+   }
+ 
++#if __cplusplus >= 201402L
++  inline path&
++  path::operator+=(__basic_string_view<value_type> __x)
++  {
++    _M_pathname.append(__x.data(), __x.size());
++    _M_split_cmpts();
++    return *this;
++  }
++#endif
++
+   template<typename _CharT>
+     inline path::_Path<_CharT*, _CharT*>&
+     path::operator+=(_CharT __x)
+@@ -892,6 +953,12 @@
+   inline int
+   path::compare(const value_type* __s) const { return compare(path(__s)); }
+ 
++#if __cplusplus >= 201402L
++  inline int
++  path::compare(__basic_string_view<value_type> __s) const
++  { return compare(path(__s)); }
++#endif
++
+   inline path
+   path::filename() const { return empty() ? path() : *--end(); }
+ 
+Index: libstdc++-v3/include/experimental/bits/fs_dir.h
+===================================================================
+--- a/src/libstdc++-v3/include/experimental/bits/fs_dir.h	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/include/experimental/bits/fs_dir.h	(.../branches/gcc-6-branch)
+@@ -312,6 +312,7 @@
+     }
+ 
+     void pop();
++    void pop(error_code&);
+ 
+     void disable_recursion_pending() { _M_pending = false; }
+ 
 Index: libstdc++-v3/include/experimental/bits/fs_fwd.h
 ===================================================================
 --- a/src/libstdc++-v3/include/experimental/bits/fs_fwd.h	(.../tags/gcc_6_2_0_release)
@@ -3535,6 +4337,15 @@ Index: libstdc++-v3/include/experimental/bits/fs_fwd.h
  #endif
  
    /**
+@@ -159,7 +162,7 @@
+       unknown		=  0xFFFF,
+       add_perms		= 0x10000,
+       remove_perms	= 0x20000,
+-      resolve_symlinks	= 0x40000
++      symlink_nofollow	= 0x40000
+   };
+ 
+   constexpr perms
 Index: libstdc++-v3/include/experimental/numeric
 ===================================================================
 --- a/src/libstdc++-v3/include/experimental/numeric	(.../tags/gcc_6_2_0_release)
@@ -5861,7 +6672,102 @@ Index: libstdc++-v3/ChangeLog
 ===================================================================
 --- a/src/libstdc++-v3/ChangeLog	(.../tags/gcc_6_2_0_release)
 +++ b/src/libstdc++-v3/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,753 @@
+@@ -1,3 +1,848 @@
++2016-12-12  Jonathan Wakely  <jwakely at redhat.com>
++
++	* testsuite/experimental/filesystem/operations/is_empty.cc:
++	Remove stray character at end of dg-do directive.
++
++2016-12-12  Jonathan Wakely  <jwakely at redhat.com>
++
++	Backport from mainline
++	PR libstdc++/70975
++	PR libstdc++/71337
++	PR libstdc++/78111
++	* include/experimental/bits/fs_dir.h (recursive_directory_iterator):
++	Overload pop (LWG 2706).
++	* include/experimental/bits/fs_fwd.h (perms::resolve_symlinks):
++	Replace with symlink_nofollow (LWG 2720).
++	* include/experimental/bits/fs_ops.h
++	(exists(const path&, error_code&)): Clear error if status is known
++	(LWG 2725).
++	* include/experimental/bits/fs_path.h (__is_path_src)
++	(_S_range_begin, _S_range_end): Overload to treat string_view as a
++	Source object.
++	(path::operator+=, path::compare): Overload for basic_string_view.
++	(path::path(string_type&&))
++	(path::operator=(string&&), path::assign(string_type&&)): Define
++	construction and assignment from string_type rvalues (LWG 2707).
++	(path::_S_convert<_Iter>(_Iter, _Iter)): Remove cv-qualifiers from
++	iterator's value_type.
++	(path::_S_convert<_Iter>(_Iter __first, __null_terminated)): Likewise.
++	Do not use operation not supported by input iterators.
++	(path::__is_path_iter_src): Add partial specialization for const
++	encoded character types.
++	* src/filesystem/dir.cc (open_dir): Return same value for errors
++	whether ignored or not.
++	(_Dir::advance(error_code*, directory_options)): Return false on
++	error.
++	(directory_iterator(const path&, directory_options, error_code*)):
++	Create end iterator on error (LWG 2723).
++	(recursive_directory_iterator(const path&, directory_options,
++	error_code*)): Likewise.
++	(recursive_directory_iterator::increment): Reset state on error.
++	(recursive_directory_iterator::pop): Define new overload.
++	* src/filesystem/ops.cc (canonical): Set error for non-existent path.
++	(file_time): Take error_code parameter and check for overflow.
++	(close_fd): Remove.
++	(do_copy_file): Report an error if source or destination is not a
++	regular file (LWG 2712). Pass error_code in file_time calls.  Just
++	use close(3) instead of close_fd, to prevent retrying on error.
++	Check if _GLIBCXX_USE_FCHMODAT is defined.
++	[_GLIBCXX_USE_SENDFILE]: Fallback to read/write operations in case
++	sendfile fails with ENOSYS or EINVAL. Pass non-null pointer to
++	sendfile for offset argument.
++	(copy): Update comment to refer to LWG 2681. Implement 2682 and 2683
++	resolutions.
++	(equivalent): Fix error handling and result when only one file exists.
++	(is_empty): Fix error handling.
++	(last_write_time(const path&, error_code&)): Pass error_code in
++	file_time calls.
++	(last_write_time(const path&, file_time_type, error_code&)): Handle
++	negative times correctly.
++	(permissions(const path&, perms, error_code&)): Handle
++	symlink_nofollow.
++	(read_symlink): Add missing ec.clear().
++	(status(const path&, error_code&)): Handle EOVERFLOW.
++	(temp_directory_path): Pass error_code argument to other filesystem
++	operations.
++	* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
++	Update expected behaviour on error.
++	* testsuite/experimental/filesystem/iterators/pop.cc: New.
++	* testsuite/experimental/filesystem/iterators/
++	recursive_directory_iterator.cc: Update expected behaviour on error.
++	* testsuite/experimental/filesystem/operations/copy.cc: Update
++	expected behaviour for copying directories with create_symlinks.
++	Verify that error_code arguments are cleared if there's no error.
++	Remove files created by tests. Test copying directories.
++	* testsuite/experimental/filesystem/operations/copy_file.cc: Remove
++	files created by tests.
++	* testsuite/experimental/filesystem/operations/create_symlink.cc: New.
++	* testsuite/experimental/filesystem/operations/equivalent.cc: New.
++	* testsuite/experimental/filesystem/operations/exists.cc: Test
++	overload taking an error_code.
++	* testsuite/experimental/filesystem/operations/is_empty.cc: New.
++	* testsuite/experimental/filesystem/operations/last_write_time.cc:
++	New.
++	* testsuite/experimental/filesystem/operations/permissions.cc: Test
++	overload taking error_code. Test symlink_nofollow on non-symlinks.
++	* testsuite/experimental/filesystem/operations/read_symlink.cc: New.
++	* testsuite/experimental/filesystem/operations/remove_all.cc: New.
++	* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
++	Add testcase for inaccessible directory.
++	* testsuite/experimental/filesystem/path/construct/range.cc: Test
++	construction from input iterators with const value types.
++	* testsuite/experimental/filesystem/path/construct/string_view.cc:
++	New.
++	* testsuite/util/testsuite_fs.h (scoped_file): Define RAII helper.
++
 +2016-12-09  Jonathan Wakely  <jwakely at redhat.com>
 +
 +	Backport from mainline
@@ -7164,6 +8070,1475 @@ Index: libstdc++-v3/testsuite/experimental/unordered_map/erasure.cc
  // with this library; see the file COPYING3.  If not see
  // <http://www.gnu.org/licenses/>.
  
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,156 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++// 15.25 Permissions [fs.op.last_write_time]
++
++#include <experimental/filesystem>
++#include <testsuite_fs.h>
++#include <testsuite_hooks.h>
++
++#ifdef _GLIBCXX_HAVE_FCNTL_H
++# include <fcntl.h>
++#endif
++#if _GLIBCXX_HAVE_UTIME_H
++# include <utime.h>
++#endif
++
++using time_type = std::experimental::filesystem::file_time_type;
++
++void
++test01()
++{
++  // read times
++
++  auto p = __gnu_test::nonexistent_path();
++  std::error_code ec;
++  time_type mtime = last_write_time(p, ec);
++  VERIFY( ec );
++  VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
++#if __cpp_exceptions
++  bool caught = false;
++  try {
++    mtime = last_write_time(p);
++  } catch (std::system_error const& e) {
++    caught = true;
++    ec = e.code();
++  }
++  VERIFY( caught );
++  VERIFY( ec );
++  VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
++#endif
++
++  __gnu_test::scoped_file file(p);
++  VERIFY( exists(p) );
++  mtime = last_write_time(p, ec);
++  VERIFY( !ec );
++  VERIFY( mtime <= time_type::clock::now() );
++  VERIFY( mtime == last_write_time(p) );
++
++  auto end_of_time = time_type::duration::max();
++  auto last_second
++    = std::chrono::duration_cast<std::chrono::seconds>(end_of_time).count();
++  if (last_second > std::numeric_limits<std::time_t>::max())
++    return; // can't test overflow
++
++#if _GLIBCXX_USE_UTIMENSAT
++  struct ::timespec ts[2];
++  ts[0].tv_sec = 0;
++  ts[0].tv_nsec = UTIME_NOW;
++  ts[1].tv_sec = std::numeric_limits<std::time_t>::max() - 1;
++  ts[1].tv_nsec = 0;
++  VERIFY( !::utimensat(AT_FDCWD, p.c_str(), ts, 0) );
++#elif _GLIBCXX_HAVE_UTIME_H
++  ::utimbuf times;
++  times.modtime = std::numeric_limits<std::time_t>::max() - 1;
++  times.actime = std::numeric_limits<std::time_t>::max() - 1;
++  VERIFY( !::utime(p.c_str(), &times) );
++#else
++  return;
++#endif
++
++  mtime = last_write_time(p, ec);
++  VERIFY( ec );
++  VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
++  VERIFY( mtime == time_type::min() );
++
++#if __cpp_exceptions
++  caught = false;
++  try {
++    mtime = last_write_time(p);
++  } catch (std::system_error const& e) {
++    caught = true;
++    ec = e.code();
++  }
++  VERIFY( caught );
++  VERIFY( ec );
++  VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
++#endif
++}
++
++bool approx_equal(time_type file_time, time_type expected)
++{
++  auto delta = expected - file_time;
++  if (delta < delta.zero())
++    delta = -delta;
++  return delta < std::chrono::seconds(1);
++}
++
++void
++test02()
++{
++  // write times
++
++  __gnu_test::scoped_file f;
++  std::error_code ec;
++  time_type time;
++
++  time = last_write_time(f.path);
++  last_write_time(f.path, time, ec);
++  VERIFY( !ec );
++  VERIFY( approx_equal(last_write_time(f.path), time) );
++
++  time -= std::chrono::milliseconds(1000 * 60 * 10 + 15);
++  last_write_time(f.path, time, ec);
++  VERIFY( !ec );
++  VERIFY( approx_equal(last_write_time(f.path), time) );
++
++  time += std::chrono::milliseconds(1000 * 60 * 20 + 15);
++  last_write_time(f.path, time, ec);
++  VERIFY( !ec );
++  VERIFY( approx_equal(last_write_time(f.path), time) );
++
++  time = time_type();
++  last_write_time(f.path, time, ec);
++  VERIFY( !ec );
++  VERIFY( approx_equal(last_write_time(f.path), time) );
++
++  time -= std::chrono::milliseconds(1000 * 60 * 10 + 15);
++  last_write_time(f.path, time, ec);
++  VERIFY( !ec );
++  VERIFY( approx_equal(last_write_time(f.path), time) );
++}
++
++int
++main()
++{
++  test01();
++  test02();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc	(.../branches/gcc-6-branch)
+@@ -46,6 +46,7 @@
+ 
+   std::error_code ec;
+   fs::path p1 = fs::temp_directory_path(ec);
++  VERIFY( !ec );
+   VERIFY( exists(p1) );
+ 
+   fs::path p2 = fs::temp_directory_path();
+@@ -65,6 +66,7 @@
+   std::error_code ec;
+   fs::path p = fs::temp_directory_path(ec);
+   VERIFY( ec );
++  VERIFY( p == fs::path() );
+ 
+   std::error_code ec2;
+   try {
+@@ -75,10 +77,54 @@
+   VERIFY( ec2 == ec );
+ }
+ 
++void
++test03()
++{
++  auto p = __gnu_test::nonexistent_path();
++  create_directories(p/"tmp");
++  permissions(p, fs::perms::none);
++  setenv("TMPDIR", (p/"tmp").c_str(), 1);
++  std::error_code ec;
++  auto r = fs::temp_directory_path(ec); // libstdc++/PR71337
++  VERIFY( ec == std::make_error_code(std::errc::permission_denied) );
++  VERIFY( r == fs::path() );
+ 
++  std::error_code ec2;
++  try {
++    fs::temp_directory_path();
++  } catch (const fs::filesystem_error& e) {
++    ec2 = e.code();
++  }
++  VERIFY( ec2 == ec );
++
++  permissions(p, fs::perms::owner_all, ec);
++  remove_all(p, ec);
++}
++
++void
++test04()
++{
++  __gnu_test::scoped_file f;
++  setenv("TMPDIR", f.path.c_str(), 1);
++  std::error_code ec;
++  auto r = fs::temp_directory_path(ec);
++  VERIFY( ec == std::make_error_code(std::errc::not_a_directory) );
++  VERIFY( r == fs::path() );
++
++  std::error_code ec2;
++  try {
++    fs::temp_directory_path();
++  } catch (const fs::filesystem_error& e) {
++    ec2 = e.code();
++  }
++  VERIFY( ec2 == ec );
++}
++
+ int
+ main()
+ {
+   test01();
+   test02();
++  test03();
++  test04();
+ }
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc	(.../branches/gcc-6-branch)
+@@ -73,6 +73,9 @@
+   VERIFY( !ec );
+   VERIFY( exists(to) );
+   VERIFY( file_size(to) == file_size(from) );
++
++  remove(from);
++  remove(to);
+ }
+ 
+ int
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/create_symlink.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/create_symlink.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/create_symlink.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,93 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_hooks.h>
++#include <testsuite_fs.h>
++
++namespace fs = std::experimental::filesystem;
++
++void
++test01()
++{
++  std::error_code ec, ec2;
++  __gnu_test::scoped_file f;
++  auto tgt = f.path;
++
++  // Test empty path.
++  fs::path p;
++  create_symlink(tgt, p, ec );
++  VERIFY( ec );
++  try
++  {
++    create_symlink(tgt, p);
++  }
++  catch (const std::experimental::filesystem::filesystem_error& ex)
++  {
++    ec2 = ex.code();
++    VERIFY( ex.path1() == tgt );
++    VERIFY( ex.path2() == p );
++  }
++  VERIFY( ec2 == ec );
++}
++
++void
++test02()
++{
++  std::error_code ec, ec2;
++  __gnu_test::scoped_file f;
++  auto tgt = f.path;
++
++  // Test non-existent path
++  auto p = __gnu_test::nonexistent_path();
++  VERIFY( !exists(p) );
++
++  create_symlink(tgt, p, ec); // create the symlink once
++  VERIFY( !ec );
++  VERIFY( exists(p) );
++  VERIFY( is_symlink(p) );
++  remove(p);
++  create_symlink(tgt, p); // create the symlink again
++  VERIFY( exists(p) );
++  VERIFY( is_symlink(p) );
++
++  create_symlink(tgt, p, ec); // Try to create existing symlink
++  VERIFY( ec );
++  try
++  {
++    create_symlink(tgt, p);
++  }
++  catch (const std::experimental::filesystem::filesystem_error& ex)
++  {
++    ec2 = ex.code();
++    VERIFY( ex.path1() == tgt );
++    VERIFY( ex.path2() == p );
++  }
++  VERIFY( ec2 == ec );
++
++  remove(p);
++}
++
++int
++main()
++{
++  test01();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc	(.../branches/gcc-6-branch)
+@@ -21,7 +21,6 @@
+ // 15.3 Copy [fs.op.copy]
+ 
+ #include <experimental/filesystem>
+-#include <fstream>
+ #include <testsuite_fs.h>
+ #include <testsuite_hooks.h>
+ 
+@@ -44,7 +43,7 @@
+   fs::copy(".", ".", fs::copy_options::none, ec);
+   VERIFY( ec );
+ 
+-  std::ofstream{p.native()};
++  __gnu_test::scoped_file f(p);
+   VERIFY( fs::is_directory(".") );
+   VERIFY( fs::is_regular_file(p) );
+   ec.clear();
+@@ -51,7 +50,18 @@
+   fs::copy(".", p, fs::copy_options::none, ec);
+   VERIFY( ec );
+ 
+-  remove(p, ec);
++  auto to = __gnu_test::nonexistent_path();
++  ec.clear();
++  auto opts = fs::copy_options::create_symlinks;
++  fs::copy("/", to, opts, ec);
++  VERIFY( ec == std::make_error_code(std::errc::is_a_directory) );
++  VERIFY( !exists(to) );
++
++  ec.clear();
++  opts != fs::copy_options::recursive;
++  fs::copy("/", to, opts, ec);
++  VERIFY( ec == std::make_error_code(std::errc::is_a_directory) );
++  VERIFY( !exists(to) );
+ }
+ 
+ // Test is_symlink(f) case.
+@@ -62,20 +72,24 @@
+ 
+   auto from = __gnu_test::nonexistent_path();
+   auto to = __gnu_test::nonexistent_path();
+-  std::error_code ec;
++  std::error_code ec, bad = std::make_error_code(std::errc::invalid_argument);
+ 
++  ec = bad;
+   fs::create_symlink(".", from, ec);
+   VERIFY( !ec );
+   VERIFY( fs::exists(from) );
+ 
++  ec = bad;
+   fs::copy(from, to, fs::copy_options::skip_symlinks, ec);
+   VERIFY( !ec );
+   VERIFY( !fs::exists(to) );
+ 
++  ec = bad;
+   fs::copy(from, to, fs::copy_options::skip_symlinks, ec);
+   VERIFY( !ec );
+   VERIFY( !fs::exists(to) );
+ 
++  ec = bad;
+   fs::copy(from, to,
+            fs::copy_options::skip_symlinks|fs::copy_options::copy_symlinks,
+            ec);
+@@ -82,9 +96,11 @@
+   VERIFY( !ec );
+   VERIFY( !fs::exists(to) );
+ 
++  ec = bad;
+   fs::copy(from, to, fs::copy_options::copy_symlinks, ec);
+   VERIFY( !ec );
+   VERIFY( fs::exists(to) );
++  VERIFY( is_symlink(to) );
+ 
+   fs::copy(from, to, fs::copy_options::copy_symlinks, ec);
+   VERIFY( ec );
+@@ -117,6 +133,9 @@
+   fs::copy(from, to);
+   VERIFY( fs::exists(to) );
+   VERIFY( fs::file_size(to) == fs::file_size(from) );
++
++  remove(from);
++  remove(to);
+ }
+ 
+ // Test is_directory(f) case.
+@@ -129,6 +148,37 @@
+   auto to = __gnu_test::nonexistent_path();
+   std::error_code ec;
+ 
++  create_directories(from/"a/b/c");
++
++  {
++    __gnu_test::scoped_file f(to);
++    copy(from, to, ec);
++    VERIFY( ec );
++  }
++
++  __gnu_test::scoped_file f1(from/"a/f1");
++  std::ofstream{f1.path} << "file one";
++  __gnu_test::scoped_file f2(from/"a/b/f2");
++  std::ofstream{f2.path} << "file two";
++
++  copy(from, to, ec);
++  VERIFY( !ec );
++  VERIFY( exists(to) && is_empty(to) );
++  remove(to);
++
++  copy(from, to, fs::copy_options::recursive, ec);
++  VERIFY( !ec );
++  VERIFY( exists(to) && !is_empty(to) );
++  VERIFY( is_regular_file(to/"a/f1") && !is_empty(to/"a/f1") );
++  VERIFY( file_size(from/"a/f1") == file_size(to/"a/f1") );
++  VERIFY( is_regular_file(to/"a/b/f2") && !is_empty(to/"a/b/f2") );
++  VERIFY( file_size(from/"a/b/f2") == file_size(to/"a/b/f2") );
++  VERIFY( is_directory(to/"a/b/c") && is_empty(to/"a/b/c") );
++
++  f1.path.clear();
++  f2.path.clear();
++  remove_all(from, ec);
++  remove_all(to, ec);
+ }
+ 
+ // Test no-op cases.
+@@ -138,10 +188,10 @@
+   bool test __attribute__((unused)) = false;
+ 
+   auto to = __gnu_test::nonexistent_path();
+-  std::error_code ec;
++  std::error_code ec = std::make_error_code(std::errc::invalid_argument);
+ 
+-  fs::copy("/", to, fs::copy_options::create_symlinks, ec);
+-  VERIFY( !ec );
++  fs::copy("/", to, fs::copy_options::copy_symlinks, ec);
++  VERIFY( !ec );  // Previous value should be cleared (LWG 2683)
+ }
+ 
+ int
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc	(.../branches/gcc-6-branch)
+@@ -21,7 +21,6 @@
+ // 15.26 Permissions [fs.op.permissions]
+ 
+ #include <experimental/filesystem>
+-#include <fstream>
+ #include <testsuite_fs.h>
+ #include <testsuite_hooks.h>
+ 
+@@ -32,7 +31,8 @@
+   using perms = std::experimental::filesystem::perms;
+ 
+   auto p = __gnu_test::nonexistent_path();
+-  std::ofstream{p.native()};
++
++  __gnu_test::scoped_file f(p);
+   VERIFY( exists(p) );
+   permissions(p, perms::owner_all);
+   VERIFY( status(p).permissions() == perms::owner_all );
+@@ -40,12 +40,113 @@
+   VERIFY( status(p).permissions() == (perms::owner_all | perms::group_read) );
+   permissions(p, perms::group_read | perms::remove_perms);
+   VERIFY( status(p).permissions() == perms::owner_all );
++}
+ 
++void
++test02()
++{
++  using perms = std::experimental::filesystem::perms;
++
++  auto p = __gnu_test::nonexistent_path();
++
++  std::error_code ec;
++  permissions(p, perms::owner_all, ec);
++  VERIFY( ec );
++
++  __gnu_test::scoped_file f(p);
++  VERIFY( exists(p) );
++
++  ec = std::make_error_code(std::errc::invalid_argument);
++  permissions(p, perms::owner_all, ec);
++  VERIFY( !ec );
++  VERIFY( status(p).permissions() == perms::owner_all );
++  permissions(p, perms::group_read | perms::add_perms, ec);
++  VERIFY( !ec );
++  VERIFY( status(p).permissions() == (perms::owner_all | perms::group_read) );
++  permissions(p, perms::group_read | perms::remove_perms, ec);
++  VERIFY( !ec );
++  VERIFY( status(p).permissions() == perms::owner_all );
++}
++
++void
++test03()
++{
++  using perms = std::experimental::filesystem::perms;
++
++  __gnu_test::scoped_file f;
++  VERIFY( exists(f.path) );
++
++  auto p = __gnu_test::nonexistent_path();
++  create_symlink(f.path, p);
++
++  std::error_code ec, ec2;
++  permissions(p, perms::owner_all | perms::symlink_nofollow, ec);
++  try
++  {
++    permissions(p, perms::owner_all | perms::symlink_nofollow);
++  }
++  catch (const std::experimental::filesystem::filesystem_error& ex)
++  {
++    ec2 = ex.code();
++    VERIFY( ex.path1() == p );
++  }
++  // Both calls should succeed, or both should fail with same error:
++  VERIFY( ec == ec2 );
++
+   remove(p);
+ }
+ 
++void
++test04()
++{
++  using perms = std::experimental::filesystem::perms;
++
++  auto p = __gnu_test::nonexistent_path();
++  create_symlink(__gnu_test::nonexistent_path(), p);
++
++  std::error_code ec, ec2;
++  permissions(p, perms::owner_all, ec);
++  VERIFY( ec );
++  try
++  {
++    permissions(p, perms::owner_all);
++  }
++  catch (const std::experimental::filesystem::filesystem_error& ex)
++  {
++    ec2 = ex.code();
++    VERIFY( ex.path1() == p );
++  }
++  VERIFY( ec == ec2 );
++
++  remove(p);
++}
++
++void
++test05()
++{
++  using perms = std::experimental::filesystem::perms;
++  std::error_code ec;
++
++  __gnu_test::scoped_file f;
++  auto p = perms::owner_write;
++
++  // symlink_nofollow should not give an error for non-symlinks
++  permissions(f.path, p|perms::symlink_nofollow, ec);
++  VERIFY( !ec );
++  auto st = status(f.path);
++  VERIFY( st.permissions() == p );
++  p |= perms::owner_read;
++  permissions(f.path, p|perms::symlink_nofollow, ec);
++  st = status(f.path);
++  VERIFY( st.permissions() == p );
++}
++
+ int
+ main()
+ {
+   test01();
++  test02();
++  test03();
++  test04();
++  test05();
+ }
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/equivalent.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,74 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_fs.h>
++#include <testsuite_hooks.h>
++
++namespace fs = std::experimental::filesystem;
++
++
++void
++test01()
++{
++  auto p1 = __gnu_test::nonexistent_path();
++  auto p2 = __gnu_test::nonexistent_path();
++  std::error_code ec;
++  bool result;
++
++  result = equivalent(p1, p2, ec);
++  VERIFY( ec );
++  VERIFY( !result );
++  const auto bad_ec = ec;
++
++  __gnu_test::scoped_file f1(p1);
++  result = equivalent(p1, p2, ec);
++  VERIFY( !ec );
++  VERIFY( !result );
++
++  __gnu_test::scoped_file f2(p2);
++  ec = bad_ec;
++  result = equivalent(p1, p2, ec);
++  VERIFY( !ec );
++  VERIFY( !result );
++
++  auto p3 = __gnu_test::nonexistent_path();
++  create_hard_link(p1, p3, ec);
++  if (ec)
++    return;  // hard links not supported
++  __gnu_test::scoped_file f3(p3, __gnu_test::scoped_file::adopt_file);
++
++  ec = bad_ec;
++  result = equivalent(p1, p3, ec);
++  VERIFY( !ec );
++  VERIFY( result );
++
++  ec = bad_ec;
++  result = equivalent(p2, p3, ec);
++  VERIFY( !ec );
++  VERIFY( !result );
++}
++
++int
++main()
++{
++  test01();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/exists.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/exists.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/exists.cc	(.../branches/gcc-6-branch)
+@@ -34,6 +34,18 @@
+   VERIFY( exists(path{"."}) );
+   VERIFY( exists(path{".."}) );
+   VERIFY( exists(std::experimental::filesystem::current_path()) );
++
++  std::error_code ec = std::make_error_code(std::errc::invalid_argument);
++  VERIFY( exists(path{"/"}, ec) );
++  VERIFY( !ec );
++  VERIFY( exists(path{"/."}, ec) );
++  VERIFY( !ec );
++  VERIFY( exists(path{"."}, ec) );
++  VERIFY( !ec );
++  VERIFY( exists(path{".."}, ec) );
++  VERIFY( !ec );
++  VERIFY( exists(std::experimental::filesystem::current_path(), ec) );
++  VERIFY( !ec );
+ }
+ 
+ void
+@@ -43,6 +55,10 @@
+ 
+   path rel = __gnu_test::nonexistent_path();
+   VERIFY( !exists(rel) );
++
++  std::error_code ec = std::make_error_code(std::errc::invalid_argument);
++  VERIFY( !exists(rel, ec) );
++  VERIFY( !ec ); // DR 2725
+ }
+ 
+ void
+@@ -52,8 +68,40 @@
+ 
+   path abs = absolute(__gnu_test::nonexistent_path());
+   VERIFY( !exists(abs) );
++
++  std::error_code ec = std::make_error_code(std::errc::invalid_argument);
++  VERIFY( !exists(abs, ec) );
++  VERIFY( !ec ); // DR 2725
+ }
+ 
++void
++test04()
++{
++  using perms = std::experimental::filesystem::perms;
++  path p = __gnu_test::nonexistent_path();
++  create_directory(p);
++  permissions(p, perms::all | perms::remove_perms);
++
++  auto unr = p / "unreachable";
++  std::error_code ec;
++  VERIFY( !exists(unr, ec) );
++  VERIFY( ec == std::errc::permission_denied );
++  ec.clear();
++  try
++  {
++    exists(unr);
++  }
++  catch(const std::experimental::filesystem::filesystem_error& ex)
++  {
++    ec = ex.code();
++    VERIFY( ex.path1() == unr );
++  }
++  VERIFY( ec == std::errc::permission_denied );
++
++  permissions(p, perms::owner_all);
++  remove(p);
++}
++
+ int
+ main()
+ {
+@@ -60,4 +108,5 @@
+   test01();
+   test02();
+   test03();
++  test04();
+ }
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/read_symlink.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/read_symlink.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/read_symlink.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,51 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_hooks.h>
++#include <testsuite_fs.h>
++
++namespace fs = std::experimental::filesystem;
++
++void
++test01()
++{
++  auto p = __gnu_test::nonexistent_path();
++  std::error_code ec;
++
++  read_symlink(p, ec);
++  VERIFY( ec );
++
++  fs::path tgt = ".";
++  create_symlink(tgt, p);
++
++  auto result = read_symlink(p, ec);
++  VERIFY( !ec );
++  VERIFY( result == tgt );
++
++  remove(p);
++}
++
++int
++main()
++{
++  test01();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,92 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_hooks.h>
++#include <testsuite_fs.h>
++
++namespace fs = std::experimental::filesystem;
++
++void
++test01()
++{
++  std::error_code ec;
++  std::uintmax_t n;
++
++  n = fs::remove_all("", ec);
++  VERIFY( ec );
++  VERIFY( n == std::uintmax_t(-1) );
++
++  auto p = __gnu_test::nonexistent_path();
++  ec.clear();
++  n = remove_all(p, ec);
++  VERIFY( ec );
++  VERIFY( n == std::uintmax_t(-1) );
++
++  const auto bad_ec = ec;
++  auto link = __gnu_test::nonexistent_path();
++  create_symlink(p, link);  // dangling symlink
++  ec = bad_ec;
++  n = remove_all(link, ec);
++  VERIFY( !ec );
++  VERIFY( n == 1 );
++  VERIFY( !exists(symlink_status(link)) ); // DR 2721
++
++  __gnu_test::scoped_file f(p);
++  create_symlink(p, link);
++  ec = bad_ec;
++  n = remove_all(link, ec);
++  VERIFY( !ec );
++  VERIFY( n == 1 );
++  VERIFY( !exists(symlink_status(link)) );  // The symlink is removed, but
++  VERIFY( exists(p) );                      // its target is not.
++
++  auto dir = __gnu_test::nonexistent_path();
++  create_directories(dir/"a/b/c");
++  ec = bad_ec;
++  n = remove_all(dir/"a", ec);
++  VERIFY( !ec );
++  VERIFY( n == 3 );
++  VERIFY( exists(dir) );
++  VERIFY( !exists(dir/"a") );
++
++  create_directories(dir/"a/b/c");
++  __gnu_test::scoped_file a1(dir/"a/1");
++  __gnu_test::scoped_file a2(dir/"a/2");
++  __gnu_test::scoped_file b1(dir/"a/b/1");
++  __gnu_test::scoped_file b2(dir/"a/b/2");
++  ec = bad_ec;
++  n = remove_all(dir, ec);
++  VERIFY( !ec );
++  VERIFY( n == 8 );
++  VERIFY( !exists(dir) );
++
++  a1.path.clear();
++  a2.path.clear();
++  b1.path.clear();
++  b2.path.clear();
++}
++
++int
++main()
++{
++  test01();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/operations/is_empty.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/operations/is_empty.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/operations/is_empty.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,109 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_hooks.h>
++#include <testsuite_fs.h>
++
++namespace fs = std::experimental::filesystem;
++
++void
++test01()
++{
++  auto p = __gnu_test::nonexistent_path();
++  create_directory(p);
++  permissions(p, fs::perms::none);
++  std::error_code ec, ec2;
++
++  bool result = fs::is_empty(p, ec);
++  VERIFY( ec == std::make_error_code(std::errc::permission_denied) );
++  VERIFY( !result );
++
++  try {
++    fs::is_empty(p);
++  } catch (const fs::filesystem_error& e) {
++    ec2 = e.code();
++  }
++  VERIFY( ec2 == ec );
++
++  result = fs::is_empty(p/"f", ec);
++  VERIFY( ec == std::make_error_code(std::errc::permission_denied) );
++  VERIFY( !result );
++
++  try {
++    fs::is_empty(p/"f");
++  } catch (const fs::filesystem_error& e) {
++    ec2 = e.code();
++  }
++  VERIFY( ec2 == ec );
++
++  permissions(p, fs::perms::owner_all, ec);
++  remove_all(p, ec);
++}
++
++void
++test02()
++{
++  auto p = __gnu_test::nonexistent_path();
++  create_directory(p);
++  std::error_code ec, bad_ec = make_error_code(std::errc::invalid_argument);
++  bool empty;
++
++  ec = bad_ec;
++  empty = is_empty(p, ec);
++  VERIFY( !ec );
++  VERIFY( empty );
++  empty = is_empty(p);
++  VERIFY( empty );
++
++  __gnu_test::scoped_file f(p/"f");
++  ec = bad_ec;
++  empty = is_empty(f.path, ec);
++  VERIFY( !ec );
++  VERIFY( empty );
++  empty = is_empty(f.path);
++  VERIFY( empty );
++
++  std::ofstream{f.path.native()} << "data";
++  ec = bad_ec;
++  empty = is_empty(p, ec);
++  VERIFY( !ec );
++  VERIFY( !empty );
++  empty = is_empty(p);
++  VERIFY( !empty );
++
++  ec = bad_ec;
++  empty = is_empty(p, ec);
++  VERIFY( !ec );
++  VERIFY( !empty );
++  empty = is_empty(p);
++  VERIFY( !empty );
++
++  f.path.clear();
++  remove_all(p, ec);
++}
++
++int
++main()
++{
++  test01();
++  test02();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc	(.../branches/gcc-6-branch)
+@@ -34,7 +34,7 @@
+   const auto p = __gnu_test::nonexistent_path();
+   fs::directory_iterator iter(p, ec);
+   VERIFY( ec );
+-  VERIFY( iter != fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test empty directory.
+   create_directory(p, fs::current_path(), ec);
+@@ -41,7 +41,7 @@
+   VERIFY( !ec );
+   iter = fs::directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter == fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test non-empty directory.
+   create_directory_symlink(p, p / "l", ec);
+@@ -51,7 +51,7 @@
+   VERIFY( iter != fs::directory_iterator() );
+   VERIFY( iter->path() == p/"l" );
+   ++iter;
+-  VERIFY( iter == fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible directory.
+   permissions(p, fs::perms::none, ec);
+@@ -58,13 +58,13 @@
+   VERIFY( !ec );
+   iter = fs::directory_iterator(p, ec);
+   VERIFY( ec );
+-  VERIFY( iter != fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible directory, skipping permission denied.
+   const auto opts = fs::directory_options::skip_permission_denied;
+   iter = fs::directory_iterator(p, opts, ec);
+   VERIFY( !ec );
+-  VERIFY( iter == fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   permissions(p, fs::perms::owner_all, ec);
+   remove_all(p, ec);
+@@ -84,12 +84,12 @@
+   // Test post-increment (libstdc++/71005)
+   auto iter = fs::directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter != fs::directory_iterator() );
++  VERIFY( iter != end(iter) );
+   const auto entry1 = *iter;
+   const auto entry2 = *iter++;
+   VERIFY( entry1 == entry2 );
+   VERIFY( entry1.path() == p/"l" );
+-  VERIFY( iter == fs::directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   remove_all(p, ec);
+ }
+Index: libstdc++-v3/testsuite/experimental/filesystem/iterators/pop.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/pop.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/pop.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,108 @@
++// 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 "-lstdc++fs" }
++// { dg-do run { target c++11 } }
++// { dg-require-filesystem-ts "" }
++
++#include <experimental/filesystem>
++#include <testsuite_hooks.h>
++#include <testsuite_fs.h>
++
++namespace fs = std::experimental::filesystem;
++
++void
++test01()
++{
++  std::error_code ec;
++  fs::recursive_directory_iterator dir;
++  dir.pop(ec);  // This is undefined, but our implementation
++  VERIFY( ec ); // checks and returns an error.
++  VERIFY( dir == end(dir) );
++
++  std::error_code ec2;
++  try
++  {
++    dir.pop();
++  }
++  catch (const fs::filesystem_error& ex)
++  {
++    ec2 = ex.code();
++  }
++  VERIFY( ec2 == ec );
++}
++
++void
++test02()
++{
++  std::error_code ec = make_error_code(std::errc::interrupted);
++  const auto p = __gnu_test::nonexistent_path();
++  create_directories(p / "d1/d2/d3");
++  for (int i = 0; i < 3; ++i)
++  {
++    fs::recursive_directory_iterator dir(p);
++    std::advance(dir, i);
++    VERIFY( dir.depth() == i );
++    dir.pop(ec);
++    VERIFY( !ec );
++    VERIFY( dir == end(dir) );
++
++    dir = fs::recursive_directory_iterator(p);
++    std::advance(dir, i);
++    VERIFY( dir.depth() == i );
++    dir.pop();
++    VERIFY( dir == end(dir) );
++  }
++  remove_all(p, ec);
++}
++
++void
++test03()
++{
++  std::error_code ec = make_error_code(std::errc::interrupted);
++  const auto p = __gnu_test::nonexistent_path();
++  create_directories(p / "d1/d2/d3");
++  create_directories(p / "d1/d2/e3");
++  create_directories(p / "d1/e2/d3");
++  for (int i = 0; i < 3; ++i)
++  {
++    fs::recursive_directory_iterator dir(p);
++    std::advance(dir, i);
++    int expected_depth = i;
++    VERIFY( dir.depth() == expected_depth );
++    dir.pop(ec);
++    VERIFY( !ec );
++    if (dir != end(dir))
++      VERIFY( dir.depth() == (expected_depth - 1) );
++
++    dir = fs::recursive_directory_iterator(p);
++    std::advance(dir, i);
++    VERIFY( dir.depth() == i );
++    dir.pop();
++    if (dir != end(dir))
++      VERIFY( dir.depth() == (i -1) );
++  }
++  remove_all(p, ec);
++}
++
++int
++main()
++{
++  test01();
++  test02();
++  test03();
++}
+Index: libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc	(.../branches/gcc-6-branch)
+@@ -34,7 +34,7 @@
+   const auto p = __gnu_test::nonexistent_path();
+   fs::recursive_directory_iterator iter(p, ec);
+   VERIFY( ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test empty directory.
+   create_directory(p, fs::current_path(), ec);
+@@ -41,7 +41,7 @@
+   VERIFY( !ec );
+   iter = fs::recursive_directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter == fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test non-empty directory.
+   create_directories(p / "d1/d2");
+@@ -48,12 +48,12 @@
+   VERIFY( !ec );
+   iter = fs::recursive_directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter != end(iter) );
+   VERIFY( iter->path() == p/"d1" );
+   ++iter;
+   VERIFY( iter->path() == p/"d1/d2" );
+   ++iter;
+-  VERIFY( iter == fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible directory.
+   permissions(p, fs::perms::none, ec);
+@@ -60,13 +60,13 @@
+   VERIFY( !ec );
+   iter = fs::recursive_directory_iterator(p, ec);
+   VERIFY( ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible directory, skipping permission denied.
+   const auto opts = fs::directory_options::skip_permission_denied;
+   iter = fs::recursive_directory_iterator(p, opts, ec);
+   VERIFY( !ec );
+-  VERIFY( iter == fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible sub-directory.
+   permissions(p, fs::perms::owner_all, ec);
+@@ -75,23 +75,24 @@
+   VERIFY( !ec );
+   iter = fs::recursive_directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter != end(iter) );
+   VERIFY( iter->path() == p/"d1" );
+   ++iter;              // should recurse into d1
+   VERIFY( iter->path() == p/"d1/d2" );
+   iter.increment(ec);  // should fail to recurse into p/d1/d2
+   VERIFY( ec );
++  VERIFY( iter == end(iter) );
+ 
+   // Test inaccessible sub-directory, skipping permission denied.
+   iter = fs::recursive_directory_iterator(p, opts, ec);
+   VERIFY( !ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter != end(iter) );
+   VERIFY( iter->path() == p/"d1" );
+   ++iter;              // should recurse into d1
+   VERIFY( iter->path() == p/"d1/d2" );
+   iter.increment(ec);  // should fail to recurse into p/d1/d2, so skip it
+   VERIFY( !ec );
+-  VERIFY( iter == fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   permissions(p/"d1/d2", fs::perms::owner_all, ec);
+   remove_all(p, ec);
+@@ -110,7 +111,7 @@
+   // Test post-increment (libstdc++/71005)
+   auto iter = fs::recursive_directory_iterator(p, ec);
+   VERIFY( !ec );
+-  VERIFY( iter != fs::recursive_directory_iterator() );
++  VERIFY( iter != end(iter) );
+   const auto entry1 = *iter;
+   const auto entry2 = *iter++;
+   VERIFY( entry1 == entry2 );
+@@ -119,7 +120,7 @@
+   const auto entry4 = *iter++;
+   VERIFY( entry3 == entry4 );
+   VERIFY( entry3.path() == p/"d1/d2" );
+-  VERIFY( iter == fs::recursive_directory_iterator() );
++  VERIFY( iter == end(iter) );
+ 
+   remove_all(p, ec);
+ }
+@@ -150,7 +151,7 @@
+ 
+   // libstdc++/71004
+   const fs::recursive_directory_iterator it;
+-  VERIFY( it == fs::recursive_directory_iterator() );
++  VERIFY( it == end(it) );
+ }
+ 
+ void
+Index: libstdc++-v3/testsuite/experimental/filesystem/path/construct/range.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/path/construct/range.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/path/construct/range.cc	(.../branches/gcc-6-branch)
+@@ -1,4 +1,5 @@
+-// { dg-options "-std=gnu++11 -lstdc++fs" }
++// { dg-options "-lstdc++fs" }
++// { dg-do run { target c++11 } }
+ // { dg-require-filesystem-ts "" }
+ 
+ // Copyright (C) 2014-2016 Free Software Foundation, Inc.
+@@ -23,6 +24,7 @@
+ #include <experimental/filesystem>
+ #include <string>
+ #include <testsuite_fs.h>
++#include <testsuite_iterators.h>
+ 
+ using std::experimental::filesystem::path;
+ using __gnu_test::compare_paths;
+@@ -53,6 +55,53 @@
+     compare_paths(p1, p7);
+     compare_paths(p1, p8);
+ #endif
++
++    using __gnu_test::test_container;
++    using __gnu_test::input_iterator_wrapper;
++    // Test with input iterators and const value_types
++
++    test_container<char, input_iterator_wrapper>
++      r1((char*)s.c_str(), (char*)s.c_str() + s.size());
++    path p9(r1.begin(), r1.end());
++    compare_paths(p1, p9);
++
++    test_container<char, input_iterator_wrapper>
++      r2((char*)s.c_str(), (char*)s.c_str() + s.size() + 1); // includes null-terminator
++    path p10(r2.begin());
++    compare_paths(p1, p10);
++
++    test_container<const char, input_iterator_wrapper>
++      r3(s.c_str(), s.c_str() + s.size());
++    path p11(r3.begin(), r3.end());
++    compare_paths(p1, p11);
++
++    test_container<const char, input_iterator_wrapper>
++      r4(s.c_str(), s.c_str() + s.size() + 1); // includes null-terminator
++    path p12(r4.begin());
++    compare_paths(p1, p12);
++
++#if _GLIBCXX_USE_WCHAR_T
++    // Test with input iterators and const value_types
++    test_container<wchar_t, input_iterator_wrapper>
++      r5((wchar_t*)ws.c_str(), (wchar_t*)ws.c_str() + ws.size());
++    path p13(r5.begin(), r5.end());
++    compare_paths(p1, p13);
++
++    test_container<wchar_t, input_iterator_wrapper>
++      r6((wchar_t*)ws.c_str(), (wchar_t*)ws.c_str() + ws.size() + 1); // includes null-terminator
++    path p14(r6.begin());
++    compare_paths(p1, p14);
++
++    test_container<const wchar_t, input_iterator_wrapper>
++      r7(ws.c_str(), ws.c_str() + ws.size());
++    path p15(r7.begin(), r7.end());
++    compare_paths(p1, p15);
++
++    test_container<const wchar_t, input_iterator_wrapper>
++      r8(ws.c_str(), ws.c_str() + ws.size() + 1); // includes null-terminator
++    path p16(r8.begin());
++    compare_paths(p1, p16);
++#endif
+   }
+ }
+ 
+Index: libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc
+===================================================================
+--- a/src/libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc	(.../branches/gcc-6-branch)
+@@ -0,0 +1,56 @@
++// { dg-options "-lstdc++fs" }
++// { dg-do run { target c++14 } }
++// { dg-require-filesystem-ts "" }
++
++// 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/>.
++
++// 8.4.1 path constructors [path.construct]
++
++#include <experimental/filesystem>
++#include <experimental/string_view>
++#include <string>
++#include <testsuite_fs.h>
++
++using std::experimental::filesystem::path;
++using __gnu_test::compare_paths;
++
++void
++test01()
++{
++  for (std::string s : __gnu_test::test_paths)
++  {
++    path p1 = s;
++    std::experimental::string_view sv(s);
++    path p2 = sv;
++    compare_paths(p1, p2);
++
++#if _GLIBCXX_USE_WCHAR_T
++    std::wstring ws(s.begin(), s.end());
++    path p3 = ws;
++    std::experimental::wstring_view wsv(ws);
++    path p4 = wsv;
++    compare_paths(p1, p4);
++#endif
++  }
++}
++
++int
++main()
++{
++  test01();
++}
 Index: libstdc++-v3/testsuite/experimental/optional/cons/value.cc
 ===================================================================
 --- a/src/libstdc++-v3/testsuite/experimental/optional/cons/value.cc	(.../tags/gcc_6_2_0_release)
@@ -9410,6 +11785,51 @@ Index: libstdc++-v3/testsuite/util/testsuite_allocator.h
  #endif
  
        template<typename Tp1>
+Index: libstdc++-v3/testsuite/util/testsuite_fs.h
+===================================================================
+--- a/src/libstdc++-v3/testsuite/util/testsuite_fs.h	(.../tags/gcc_6_2_0_release)
++++ b/src/libstdc++-v3/testsuite/util/testsuite_fs.h	(.../branches/gcc-6-branch)
+@@ -23,7 +23,7 @@
+ #define _TESTSUITE_FS_H 1
+ 
+ #include <experimental/filesystem>
+-#include <iostream>
++#include <fstream>
+ #include <string>
+ #include <cstdio>
+ #include <stdlib.h>
+@@ -40,7 +40,6 @@
+   compare_paths(const std::experimental::filesystem::path& p1,
+ 		const std::experimental::filesystem::path& p2)
+   {
+-    // std::cout << "Comparing " << p1 << " and " << p2 << std::endl;
+     PATH_CHK( p1, p2, string );
+     PATH_CHK( p1, p2, empty );
+     PATH_CHK( p1, p2, has_root_path );
+@@ -95,5 +94,23 @@
+     return p;
+   }
+ 
++  // RAII helper to remove a file on scope exit.
++  struct scoped_file
++  {
++    using path_type = std::experimental::filesystem::path;
++
++    enum adopt_file_t { adopt_file };
++
++    explicit
++    scoped_file(const path_type& p = nonexistent_path()) : path(p)
++    { std::ofstream{p.native()}; }
++
++    scoped_file(path_type p, adopt_file_t) : path(p) { }
++
++    ~scoped_file() { if (!path.empty()) remove(path); }
++
++    path_type path;
++  };
++
+ } // namespace __gnu_test
+ #endif
 Index: libstdc++-v3/testsuite/20_util/duration/literals/range.cc
 ===================================================================
 --- a/src/libstdc++-v3/testsuite/20_util/duration/literals/range.cc	(.../tags/gcc_6_2_0_release)
@@ -12007,7 +14427,27 @@ Index: gcc/ChangeLog
 ===================================================================
 --- a/src/gcc/ChangeLog	(.../tags/gcc_6_2_0_release)
 +++ b/src/gcc/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,1352 @@
+@@ -1,3 +1,1372 @@
++2016-12-12  Bernd Schmidt  <bschmidt at redhat.com>
++
++	Backport from mainline
++	2016-11-07  Bernd Schmidt  <bschmidt at redhat.com>
++
++        PR rtl-optimization/77309
++        * combine.c (make_compound_operation): Allow EQ for IN_CODE, and
++        don't assume an equality comparison for plain COMPARE.
++        (simplify_comparison): Pass a more accurate code to
++        make_compound_operation.
++
++2016-12-12 Thomas Preud'homme <thomas.preudhomme at arm.com>
++
++	Backport from mainline
++	2016-11-22  Thomas Preud'homme  <thomas.preudhomme at arm.com>
++
++	PR target/77904
++	* config/arm/arm.c (thumb1_compute_save_reg_mask): Mark frame pointer
++	in save register mask if it is needed.
++
 +2016-12-11  Iain Sandoe  <iain at codesourcery.com>
 +
 +	Backport from mainline
@@ -13360,7 +15800,7 @@ Index: gcc/ChangeLog
  2016-08-22  Release Manager
  
  	* GCC 6.2.0 released.
-@@ -205,9 +1554,9 @@
+@@ -205,9 +1574,9 @@
  
  2016-08-09  Martin Jambor  <mjambor at suse.cz>
  
@@ -13566,6 +16006,56 @@ Index: gcc/testsuite/gcc.target/arm/pr48863.c
 +    __builtin_abort ();
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.target/arm/pr77904.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.target/arm/pr77904.c	(.../tags/gcc_6_2_0_release)
++++ b/src/gcc/testsuite/gcc.target/arm/pr77904.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,45 @@
++/* { dg-do run } */
++/* { dg-options "-O2" } */
++
++__attribute__ ((noinline, noclone)) void
++clobber_sp (void)
++{
++  __asm volatile ("" : : : "sp");
++}
++
++int
++main (void)
++{
++  int ret;
++
++  __asm volatile ("mov\tr4, #0xf4\n\t"
++		  "mov\tr5, #0xf5\n\t"
++		  "mov\tr6, #0xf6\n\t"
++		  "mov\tr7, #0xf7\n\t"
++		  "mov\tr0, #0xf8\n\t"
++		  "mov\tr8, r0\n\t"
++		  "mov\tr0, #0xfa\n\t"
++		  "mov\tr10, r0"
++		  : : : "r0", "r4", "r5", "r6", "r7", "r8", "r10");
++  clobber_sp ();
++
++  __asm volatile ("cmp\tr4, #0xf4\n\t"
++		  "bne\tfail\n\t"
++		  "cmp\tr5, #0xf5\n\t"
++		  "bne\tfail\n\t"
++		  "cmp\tr6, #0xf6\n\t"
++		  "bne\tfail\n\t"
++		  "cmp\tr7, #0xf7\n\t"
++		  "bne\tfail\n\t"
++		  "mov\tr0, r8\n\t"
++		  "cmp\tr0, #0xf8\n\t"
++		  "bne\tfail\n\t"
++		  "mov\tr0, r10\n\t"
++		  "cmp\tr0, #0xfa\n\t"
++		  "bne\tfail\n\t"
++		  "mov\t%0, #1\n"
++		  "fail:\n\t"
++		  "sub\tr0, #1"
++		  : "=r" (ret) : :);
++  return ret;
++}
 Index: gcc/testsuite/gcc.target/arm/empty_fiq_handler.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.target/arm/empty_fiq_handler.c	(.../tags/gcc_6_2_0_release)
@@ -18761,6 +21251,25 @@ Index: gcc/testsuite/gcc.dg/torture/pr78546-1.c
 +    __builtin_abort ();
 +  return 0;
 +}
+Index: gcc/testsuite/gcc.dg/torture/pr77309.c
+===================================================================
+--- a/src/gcc/testsuite/gcc.dg/torture/pr77309.c	(.../tags/gcc_6_2_0_release)
++++ b/src/gcc/testsuite/gcc.dg/torture/pr77309.c	(.../branches/gcc-6-branch)
+@@ -0,0 +1,14 @@
++/* { dg-do run } */
++
++int a, b;
++
++int main ()
++{
++  long c = 1 % (2 ^ b);
++  c = -c & ~(~(b ^ ~b) || a);
++
++  if (c >= 0)
++    __builtin_abort ();
++
++  return 0;
++}
 Index: gcc/testsuite/gcc.dg/torture/pr77768.c
 ===================================================================
 --- a/src/gcc/testsuite/gcc.dg/torture/pr77768.c	(.../tags/gcc_6_2_0_release)
@@ -19534,7 +22043,23 @@ Index: gcc/testsuite/ChangeLog
 ===================================================================
 --- a/src/gcc/testsuite/ChangeLog	(.../tags/gcc_6_2_0_release)
 +++ b/src/gcc/testsuite/ChangeLog	(.../branches/gcc-6-branch)
-@@ -1,3 +1,1171 @@
+@@ -1,3 +1,1187 @@
++2016-12-12  Bernd Schmidt  <bschmidt at redhat.com>
++
++	Backport from mainline
++	2016-11-07  Bernd Schmidt  <bschmidt at redhat.com>
++
++        PR rtl-optimization/77309
++        * gcc.dg/torture/pr77309.c: New test.
++
++2016-12-12 Thomas Preud'homme <thomas.preudhomme at arm.com>
++
++	Backport from mainline
++	2016-11-22  Thomas Preud'homme  <thomas.preudhomme at arm.com>
++
++	PR target/77904
++	* gcc.target/arm/pr77904.c: New test.
++
 +2016-12-11  Iain Sandoe  <iain at codesourcery.com>
 +
 +	Backport from mainline
@@ -20706,7 +23231,7 @@ Index: gcc/testsuite/ChangeLog
  2016-08-22  Release Manager
  
  	* GCC 6.2.0 released.
-@@ -150,8 +1318,8 @@
+@@ -150,8 +1334,8 @@
  
  2016-08-09  Martin Jambor  <mjambor at suse.cz>
  
@@ -20717,7 +23242,7 @@ Index: gcc/testsuite/ChangeLog
  
  2016-08-09  Richard Biener  <rguenther at suse.de>
  
-@@ -276,8 +1444,8 @@
+@@ -276,8 +1460,8 @@
  
  2016-07-20  Martin Jambor  <mjambor at suse.cz>
  
@@ -20728,7 +23253,7 @@ Index: gcc/testsuite/ChangeLog
  
  2016-07-19  Jakub Jelinek  <jakub at redhat.com>
  
-@@ -418,7 +1586,7 @@
+@@ -418,7 +1602,7 @@
  	2016-07-06  Yuri Rumyantsev  <ysrumyan at gmail.com>
  
  	PR tree-optimization/71518
@@ -20737,7 +23262,7 @@ Index: gcc/testsuite/ChangeLog
  
  2016-07-09  Thomas Koenig  <tkoenig at gcc.gnu.org>
  
-@@ -1639,7 +2807,7 @@
+@@ -1639,7 +2823,7 @@
  	* g++.dg/cpp1y/vla13.C: Same.
  	* g++.dg/cpp1y/vla14.C: Same.
  	* g++.dg/cpp1y/vla3.C: Same.
@@ -20746,7 +23271,7 @@ Index: gcc/testsuite/ChangeLog
  	* g++.dg/ubsan/vla-1.C: Same.
  
  2016-04-14  Marek Polacek  <polacek at redhat.com>
-@@ -1671,7 +2839,7 @@
+@@ -1671,7 +2855,7 @@
  	* g++.dg/cpp1y/vla13.C: New test.
  	* g++.dg/cpp1y/vla14.C: New test.
  	* g++.dg/cpp1y/vla3.C: Restore deleted test.
@@ -20755,7 +23280,7 @@ Index: gcc/testsuite/ChangeLog
  	* g++.dg/ubsan/vla-1.C: Disable exceptions.
  
  2016-04-13  Jakub Jelinek  <jakub at redhat.com>
-@@ -1699,8 +2867,8 @@
+@@ -1699,8 +2883,8 @@
  2016-04-13  Marek Polacek  <polacek at redhat.com>
  
  	PR c/70436
@@ -20766,7 +23291,7 @@ Index: gcc/testsuite/ChangeLog
  
  2016-04-13  Ilya Enkovich  <ilya.enkovich at intel.com>
  
-@@ -1947,7 +3115,7 @@
+@@ -1947,7 +3131,7 @@
  2016-04-06  Vladimir Makarov  <vmakarov at redhat.com>
  
  	PR rtl-optimization/70398
@@ -621180,6 +623705,64 @@ Index: gcc/combine.c
  
        /* If this extraction is going into the destination of a SET,
  	 make a STRICT_LOW_PART unless we made a MEM.  */
+@@ -7755,7 +7755,8 @@
+ 
+    IN_CODE says what kind of expression we are processing.  Normally, it is
+    SET.  In a memory address it is MEM.  When processing the arguments of
+-   a comparison or a COMPARE against zero, it is COMPARE.  */
++   a comparison or a COMPARE against zero, it is COMPARE, or EQ if more
++   precisely it is an equality comparison against zero.  */
+ 
+ rtx
+ make_compound_operation (rtx x, enum rtx_code in_code)
+@@ -7769,11 +7770,17 @@
+   rtx new_rtx = 0;
+   rtx tem;
+   const char *fmt;
++  bool equality_comparison = false;
+ 
+   /* Select the code to be used in recursive calls.  Once we are inside an
+      address, we stay there.  If we have a comparison, set to COMPARE,
+      but once inside, go back to our default of SET.  */
+ 
++  if (in_code == EQ)
++    {
++      equality_comparison = true;
++      in_code = COMPARE;
++    }
+   next_code = (code == MEM ? MEM
+ 	       : ((code == COMPARE || COMPARISON_P (x))
+ 		  && XEXP (x, 1) == const0_rtx) ? COMPARE
+@@ -7982,11 +7989,12 @@
+       /* If we are in a comparison and this is an AND with a power of two,
+ 	 convert this into the appropriate bit extract.  */
+       else if (in_code == COMPARE
+-	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0)
++	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0
++	       && (equality_comparison || i < GET_MODE_PRECISION (mode) - 1))
+ 	new_rtx = make_extraction (mode,
+-			       make_compound_operation (XEXP (x, 0),
+-							next_code),
+-			       i, NULL_RTX, 1, 1, 0, 1);
++				   make_compound_operation (XEXP (x, 0),
++							    next_code),
++				   i, NULL_RTX, 1, 1, 0, 1);
+ 
+       break;
+ 
+@@ -12391,7 +12399,11 @@
+      We can never remove a SUBREG for a non-equality comparison because
+      the sign bit is in a different place in the underlying object.  */
+ 
+-  op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET);
++  rtx_code op0_mco_code = SET;
++  if (op1 == const0_rtx)
++    op0_mco_code = code == NE || code == EQ ? EQ : COMPARE;
++
++  op0 = make_compound_operation (op0, op0_mco_code);
+   op1 = make_compound_operation (op1, SET);
+ 
+   if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
 Index: gcc/config.gcc
 ===================================================================
 --- a/src/gcc/config.gcc	(.../tags/gcc_6_2_0_release)
@@ -625621,7 +628204,18 @@ Index: gcc/config/arm/arm.c
        if (modconst)
          *modconst = CONST_VECTOR_ELT (op, 0);
  
-@@ -24715,6 +24710,7 @@
+@@ -19395,6 +19390,10 @@
+     if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg))
+       mask |= 1 << reg;
+ 
++  /* Handle the frame pointer as a special case.  */
++  if (frame_pointer_needed)
++    mask |= 1 << HARD_FRAME_POINTER_REGNUM;
++
+   if (flag_pic
+       && !TARGET_SINGLE_PIC_BASE
+       && arm_pic_register != INVALID_REGNUM
+@@ -24715,6 +24714,7 @@
    unsigned long live_regs_mask;
    unsigned long l_mask;
    unsigned high_regs_pushed = 0;
@@ -625629,7 +628223,7 @@ Index: gcc/config/arm/arm.c
  
    func_type = arm_current_func_type ();
  
-@@ -24737,6 +24733,7 @@
+@@ -24737,6 +24737,7 @@
  
    offsets = arm_get_frame_offsets ();
    live_regs_mask = offsets->saved_regs_mask;
@@ -625637,7 +628231,7 @@ Index: gcc/config/arm/arm.c
  
    /* Extract a mask of the ones we can give to the Thumb's push instruction.  */
    l_mask = live_regs_mask & 0x40ff;
-@@ -24803,6 +24800,7 @@
+@@ -24803,6 +24804,7 @@
  	{
  	  insn = thumb1_emit_multi_reg_push (l_mask, l_mask);
  	  RTX_FRAME_RELATED_P (insn) = 1;
@@ -625645,7 +628239,7 @@ Index: gcc/config/arm/arm.c
  
  	  offset = bit_count (l_mask) * UNITS_PER_WORD;
  	}
-@@ -24867,12 +24865,13 @@
+@@ -24867,12 +24869,13 @@
       be a push of LR and we can combine it with the push of the first high
       register.  */
    else if ((l_mask & 0xff) != 0
@@ -625660,7 +628254,7 @@ Index: gcc/config/arm/arm.c
      }
  
    if (high_regs_pushed)
-@@ -24890,7 +24889,9 @@
+@@ -24890,7 +24893,9 @@
        /* Here we need to mask out registers used for passing arguments
  	 even if they can be pushed.  This is to avoid using them to stash the high
  	 registers.  Such kind of stash may clobber the use of arguments.  */
@@ -625671,7 +628265,7 @@ Index: gcc/config/arm/arm.c
  
        if (pushable_regs == 0)
  	pushable_regs = 1 << thumb_find_work_register (live_regs_mask);
-@@ -24898,8 +24899,9 @@
+@@ -24898,8 +24903,9 @@
        while (high_regs_pushed > 0)
  	{
  	  unsigned long real_regs_mask = 0;
@@ -625682,7 +628276,7 @@ Index: gcc/config/arm/arm.c
  	    {
  	      if (pushable_regs & (1 << regno))
  		{
-@@ -24908,6 +24910,7 @@
+@@ -24908,6 +24914,7 @@
  
  		  high_regs_pushed --;
  		  real_regs_mask |= (1 << next_hi_reg);
@@ -625690,7 +628284,7 @@ Index: gcc/config/arm/arm.c
  
  		  if (high_regs_pushed)
  		    {
-@@ -24917,23 +24920,20 @@
+@@ -24917,23 +24924,20 @@
  			  break;
  		    }
  		  else
diff --git a/debian/rules.conf b/debian/rules.conf
index db9b4d9..61bd363 100644
--- a/debian/rules.conf
+++ b/debian/rules.conf
@@ -210,8 +210,8 @@ else
     BINUTILSBDV = 2.25-7~
   else ifneq (,$(filter $(distrelease),xenial))
     BINUTILSBDV = 2.26.1
-  else ifneq (,$(filter $(distrelease),sid stretch))
-    BINUTILSBDV = 2.27.51.20161124-1
+  else ifneq (,$(filter $(distrelease),sid stretch zesty))
+    BINUTILSBDV = 2.27.51.20161212
   endif
 endif
 ifeq ($(DEB_CROSS),yes)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/gcc-6.git



More information about the Reproducible-commits mailing list