aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog85
-rw-r--r--libstdc++-v3/include/bits/locale_conv.h2
-rw-r--r--libstdc++-v3/include/bits/regex.h2
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_ops.h7
-rw-r--r--libstdc++-v3/include/std/complex10
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py6
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc144
-rw-r--r--libstdc++-v3/testsuite/22_locale/conversions/buffer/3.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc191
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc37
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc4
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc19
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc1
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/remove.cc100
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc36
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc2
17 files changed, 639 insertions, 69 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cbe0fc5daa8..8db45525a7d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,88 @@
+2018-01-15 Jonathan Wakely <jwakely@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (register_type_printers): Remove
+ printer for experimental::any. Fix printers for experimental::optional
+ and experimental::basic_string_view.
+
+ Backport from mainline
+ 2018-01-04 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/83626
+ * src/filesystem/ops.cc (remove(const path&, error_code&))): Do not
+ return an error for non-existent paths. Remove unnecessary
+ symlink_status call.
+ (remove_all(const path&)): Fix type of result variable.
+ (remove_all(const path&, error_code&))): Use non-throwing increment
+ for directory iterator. Do not return an error for non-existent paths.
+ * testsuite/experimental/filesystem/operations/remove.cc: New test.
+ * testsuite/experimental/filesystem/operations/remove_all.cc: Fix
+ expected results for non-existent paths.
+
+2018-01-05 Jonathan Wakely <jwakely@redhat.com>
+
+ Backport from mainline
+ 2017-11-14 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/locale_conv.h (wbuffer_convert::_M_conv_get): Fix typo.
+ * testsuite/22_locale/conversions/buffer/3.cc: New test.
+
+ Backport from mainline
+ 2017-10-19 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/experimental/filesystem/iterators/
+ recursive_directory_iterator.cc: Ensure that error_code arguments are
+ cleared when required.
+ * testsuite/experimental/filesystem/operations/create_directory.cc:
+ Remove redundant check.
+ * testsuite/experimental/filesystem/operations/temp_directory_path.cc:
+ Ensure that error_code argument is cleared when required.
+
+ Backport from mainline
+ 2017-12-27 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/83600
+ * include/bits/regex.h (match_results::end()): Return valid iterator
+ when not ready.
+ * testsuite/28_regex/match_results/ctors/char/default.cc: Check that
+ unready objects are empty and have equal begin and end iterators.
+ * testsuite/28_regex/match_results/ctors/wchar_t/default.cc: Likewise.
+
+ Backport from mainline
+ 2017-12-27 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/83598
+ * include/bits/regex.h (basic_regex): Don't modify flags passed to
+ constructors.
+ * testsuite/28_regex/basic_regex/ctors/83598.cc: New test.
+
+ Backport from mainline
+ 2017-12-14 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/83279
+ * src/filesystem/std-ops.cc (do_copy_file): Handle sendfile not
+ copying entire file.
+
+ Backport from mainline
+ 2018-01-04 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/experimental/fs_ops.h (exists(const path&, error_code&))):
+ Only check status_known once.
+
+ Backport from mainline
+ 2017-10-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/79283
+ * src/filesystem/ops.cc (read_symlink): Handle st_size being zero.
+
+2017-12-14 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/59568
+ * include/std/complex (operator>>): Only use putback if a character
+ was successfully extracted and only set the value if a number was
+ successfully extracted.
+ * testsuite/26_numerics/complex/inserters_extractors/char/59568.cc:
+ New test.
+
2017-11-11 John David Anglin <danglin@gcc.gnu.org>
Backport from mainline
diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h
index 9667374840b..06376e9cd19 100644
--- a/libstdc++-v3/include/bits/locale_conv.h
+++ b/libstdc++-v3/include/bits/locale_conv.h
@@ -431,7 +431,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
streamsize __nbytes = sizeof(_M_get_buf) - _M_unconv;
__nbytes = std::min(__nbytes, _M_buf->in_avail());
if (__nbytes < 1)
- __nbytes == 1;
+ __nbytes = 1;
__nbytes = _M_buf->sgetn(_M_get_buf + _M_unconv, __nbytes);
if (__nbytes < 1)
return false;
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 983bdef3871..cf7aa3ee4bf 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1751,7 +1751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
const_iterator
end() const
- { return _Base_type::end() - 3; }
+ { return _Base_type::end() - (empty() ? 0 : 3); }
/**
* @brief Gets an iterator to one-past-the-end of the collection.
diff --git a/libstdc++-v3/include/experimental/bits/fs_ops.h b/libstdc++-v3/include/experimental/bits/fs_ops.h
index 62a9826d6e5..7b30a30138e 100644
--- a/libstdc++-v3/include/experimental/bits/fs_ops.h
+++ b/libstdc++-v3/include/experimental/bits/fs_ops.h
@@ -131,8 +131,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
auto __s = status(__p, __ec);
if (status_known(__s))
- __ec.clear();
- return exists(__s);
+ {
+ __ec.clear();
+ return __s.type() != file_type::not_found;
+ }
+ return false;
}
uintmax_t file_size(const path& __p);
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index 8f9703a59c8..1225c6bc44e 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -493,7 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
{
_Tp __re_x, __im_x;
- _CharT __ch;
+ _CharT __ch = _CharT();
__is >> __ch;
if (__ch == '(')
{
@@ -511,11 +511,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
__is.setstate(ios_base::failbit);
}
- else
+ else if (__is)
{
__is.putback(__ch);
- __is >> __re_x;
- __x = __re_x;
+ if (__is >> __re_x)
+ __x = __re_x;
+ else
+ __is.setstate(ios_base::failbit);
}
return __is;
}
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 040715a9073..ec3feafc5de 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1154,7 +1154,7 @@ class TemplateTypePrinter(object):
Recognizes type names that match a regular expression.
Replaces them with a formatted string which can use replacement field
{N} to refer to the \N subgroup of the regex match.
- Type printers are recusively applied to the subgroups.
+ Type printers are recursively applied to the subgroups.
This allows recognizing e.g. "std::vector<(.*), std::allocator<\\1> >"
and replacing it with "std::vector<{1}>", omitting the template argument
@@ -1335,10 +1335,10 @@ def register_type_printers(obj):
# strip the "fundamentals_v1" inline namespace from these types
add_one_template_type_printer(obj, 'optional<T>',
'experimental::fundamentals_v1::optional<(.*)>',
- 'experimental::optional<\\1>')
+ 'experimental::optional<{1}>')
add_one_template_type_printer(obj, 'basic_string_view<C>',
'experimental::fundamentals_v1::basic_string_view<(.*), std::char_traits<\\1> >',
- 'experimental::basic_string_view<\\1>')
+ 'experimental::basic_string_view<{1}>')
def register_libstdcxx_printers (obj):
"Register libstdc++ pretty-printers with objfile Obj."
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 0dcb1b410fc..d4bd5207b63 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -443,48 +443,68 @@ namespace
return false;
}
+ size_t count = from_st->st_size;
#ifdef _GLIBCXX_USE_SENDFILE
off_t offset = 0;
- const auto n = ::sendfile(out.fd, in.fd, &offset, from_st->st_size);
- if (n < 0 && (errno == ENOSYS || errno == EINVAL))
+ ssize_t n = ::sendfile(out.fd, in.fd, &offset, count);
+ 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;
+ }
+ if ((size_t)n == count)
+ {
+ if (!out.close() || !in.close())
{
ec.assign(errno, std::generic_category());
return false;
}
-
ec.clear();
return true;
+ }
+ else if (n > 0)
+ count -= n;
+#endif // _GLIBCXX_USE_SENDFILE
+
+ using std::ios;
+ __gnu_cxx::stdio_filebuf<char> sbin(in.fd, ios::in|ios::binary);
+ __gnu_cxx::stdio_filebuf<char> sbout(out.fd, ios::out|ios::binary);
+
+ if (sbin.is_open())
+ in.fd = -1;
+ if (sbout.is_open())
+ out.fd = -1;
#ifdef _GLIBCXX_USE_SENDFILE
+ if (n != 0)
+ {
+ if (n < 0)
+ n = 0;
+
+ const auto p1 = sbin.pubseekoff(n, ios::beg, ios::in);
+ const auto p2 = sbout.pubseekoff(n, ios::beg, ios::out);
+
+ const std::streampos errpos(std::streamoff(-1));
+ if (p1 == errpos || p2 == errpos)
+ {
+ ec = std::make_error_code(std::errc::io_error);
+ return false;
+ }
}
- if (n != from_st->st_size)
+#endif
+
+ if (count && !(std::ostream(&sbout) << &sbin))
{
- ec.assign(errno, std::generic_category());
+ ec = std::make_error_code(std::errc::io_error);
return false;
}
- if (!out.close() || !in.close())
+ if (!sbout.close() || !sbin.close())
{
ec.assign(errno, std::generic_category());
return false;
}
-
ec.clear();
return true;
-#endif
}
}
#endif
@@ -1199,26 +1219,45 @@ fs::read_symlink(const path& p)
fs::path fs::read_symlink(const path& p, error_code& ec)
{
+ path result;
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
stat_type st;
if (::lstat(p.c_str(), &st))
{
ec.assign(errno, std::generic_category());
- return {};
+ return result;
}
- std::string buf(st.st_size, '\0');
- ssize_t len = ::readlink(p.c_str(), &buf.front(), buf.size());
- if (len == -1)
+ std::string buf(st.st_size ? st.st_size + 1 : 128, '\0');
+ do
{
- ec.assign(errno, std::generic_category());
- return {};
+ ssize_t len = ::readlink(p.c_str(), &buf.front(), buf.size());
+ if (len == -1)
+ {
+ ec.assign(errno, std::generic_category());
+ return result;
+ }
+ else if (len == (ssize_t)buf.size())
+ {
+ if (buf.size() > 4096)
+ {
+ ec.assign(ENAMETOOLONG, std::generic_category());
+ return result;
+ }
+ buf.resize(buf.size() * 2);
+ }
+ else
+ {
+ buf.resize(len);
+ result.assign(buf);
+ ec.clear();
+ break;
+ }
}
- ec.clear();
- return path{buf.data(), buf.data()+len};
+ while (true);
#else
ec = std::make_error_code(std::errc::not_supported);
- return {};
#endif
+ return result;
}
@@ -1235,16 +1274,15 @@ fs::remove(const path& p)
bool
fs::remove(const path& p, error_code& ec) noexcept
{
- if (exists(symlink_status(p, ec)))
+ if (::remove(p.c_str()) == 0)
{
- if (::remove(p.c_str()) == 0)
- {
- ec.clear();
- return true;
- }
- else
- ec.assign(errno, std::generic_category());
+ ec.clear();
+ return true;
}
+ else if (errno == ENOENT)
+ ec.clear();
+ else
+ ec.assign(errno, std::generic_category());
return false;
}
@@ -1253,7 +1291,7 @@ std::uintmax_t
fs::remove_all(const path& p)
{
error_code ec;
- bool result = remove_all(p, ec);
+ const auto result = remove_all(p, ec);
if (ec.value())
_GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot remove all", p, ec));
return result;
@@ -1262,14 +1300,28 @@ fs::remove_all(const path& p)
std::uintmax_t
fs::remove_all(const path& p, error_code& ec) noexcept
{
- auto fs = symlink_status(p, ec);
- uintmax_t count = 0;
- if (ec.value() == 0 && fs.type() == file_type::directory)
- for (directory_iterator d(p, ec), end; ec.value() == 0 && d != end; ++d)
- count += fs::remove_all(d->path(), ec);
- if (ec.value())
+ const auto s = symlink_status(p, ec);
+ if (!status_known(s))
return -1;
- return fs::remove(p, ec) ? ++count : -1; // fs:remove() calls ec.clear()
+
+ ec.clear();
+ if (s.type() == file_type::not_found)
+ return 0;
+
+ uintmax_t count = 0;
+ if (s.type() == file_type::directory)
+ {
+ for (directory_iterator d(p, ec), end; !ec && d != end; d.increment(ec))
+ count += fs::remove_all(d->path(), ec);
+ if (ec.value() == ENOENT)
+ ec.clear();
+ else if (ec)
+ return -1;
+ }
+
+ if (fs::remove(p, ec))
+ ++count;
+ return ec ? -1 : count;
}
void
diff --git a/libstdc++-v3/testsuite/22_locale/conversions/buffer/3.cc b/libstdc++-v3/testsuite/22_locale/conversions/buffer/3.cc
new file mode 100644
index 00000000000..99a679dc124
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/conversions/buffer/3.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2017 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-do run { target c++11 } }
+
+#include <locale>
+#include <streambuf>
+#include <testsuite_hooks.h>
+
+struct streambuf : std::streambuf
+{
+ int_type underflow() override
+ {
+ if (c != '\0')
+ {
+ this->setg(&c, &c, &c + 1);
+ return *this->gptr();
+ }
+ c = '\0';
+ return traits_type::eof();
+ }
+
+private:
+ char c = 'a';
+};
+
+struct codecvt : std::codecvt<wchar_t, char, std::mbstate_t> { };
+
+void
+test01()
+{
+ // https://gcc.gnu.org/ml/libstdc++/2017-11/msg00022.html
+ streambuf sb;
+ std::wbuffer_convert<codecvt> conv(&sb);
+ VERIFY( sb.in_avail() == 0 );
+ wchar_t c = conv.sgetc();
+ VERIFY( c == L'a' );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc b/libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc
new file mode 100644
index 00000000000..e292e13311a
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc
@@ -0,0 +1,191 @@
+// Copyright (C) 2017 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/>.
+
+#include <complex>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::istringstream in(" 1 (2) ( 2.0 , 0.5 ) ");
+ std::complex<double> c1, c2, c3;
+ in >> c1 >> c2 >> c3;
+ VERIFY( in.good() );
+ VERIFY( c1.real() == 1 && c1.imag() == 0 );
+ VERIFY( c2.real() == 2 && c2.imag() == 0 );
+ VERIFY( c3.real() == 2 && c3.imag() == 0.5 );
+}
+
+void
+test02()
+{
+ std::istringstream in;
+ std::complex<double> c(-1, -1);
+ const std::complex<double> c0 = c;
+
+ in.str("a");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == 'a' );
+ VERIFY( c == c0 );
+
+ in.str(" ( ) ");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == ')' );
+ VERIFY( c == c0 );
+
+ in.str("(,");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == ',' );
+ VERIFY( c == c0 );
+
+ in.str("(b)");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == 'b' );
+ VERIFY( c == c0 );
+
+ in.str("( c)");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == 'c' );
+ VERIFY( c == c0 );
+
+ in.str("(99d");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ // VERIFY( in.get() == 'd' );
+ VERIFY( c == c0 );
+
+ in.str("(99 e");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ // VERIFY( in.get() == 'e' );
+ VERIFY( c == c0 );
+
+ in.str("(99, f");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == 'f' );
+ VERIFY( c == c0 );
+
+ in.str("(99, 88g");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ // VERIFY( in.get() == 'g' );
+ VERIFY( c == c0 );
+
+ in.str("(99, 88 h");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ // VERIFY( in.get() == 'h' );
+ VERIFY( c == c0 );
+
+ in.str("(99, )");
+ in >> c;
+ VERIFY( in.fail() );
+ in.clear();
+ VERIFY( in.get() == ')' );
+ VERIFY( c == c0 );
+}
+
+void
+test03()
+{
+ // PR libstdc++/59568
+ std::istringstream in;
+ std::complex<double> c;
+
+ in.str("");
+ in >> c;
+ VERIFY( in.fail() );
+ VERIFY( in.eof() );
+ in.clear();
+
+ in.str(" ");
+ in >> c;
+ VERIFY( in.fail() );
+ VERIFY( in.eof() );
+ in.clear();
+
+ in.str("(99");
+ in >> c;
+ VERIFY( in.fail() );
+ VERIFY( in.eof() );
+ in.clear();
+
+ in.str("(99,");
+ in >> c;
+ VERIFY( in.fail() );
+ VERIFY( in.eof() );
+ in.clear();
+
+ in.str("(99,99");
+ in >> c;
+ VERIFY( in.fail() );
+ VERIFY( in.eof() );
+ in.clear();
+}
+
+void
+test04()
+{
+ // Test noskipws handling
+ std::istringstream in;
+ const char* bad_inputs[] = {
+ " 1", " (2)", "( 2)", "(2 )", "(2 ,3)", "(2,3 )", 0
+ };
+ const std::complex<double> c0(-1, -1);
+ std::complex<double> c;
+ for (int i = 0; bad_inputs[i]; ++i)
+ {
+ c = c0;
+ in.clear();
+ in.str(bad_inputs[i]);
+ in >> std::noskipws >> c;
+ VERIFY( in.fail() );
+ VERIFY( c == c0 );
+
+ in.clear();
+ in.str(bad_inputs[i]);
+ in >> std::skipws >> c;
+ VERIFY( !in.fail() );
+ VERIFY( c != c0 );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc
new file mode 100644
index 00000000000..b958dfbe42f
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc
@@ -0,0 +1,37 @@
+// Copyright (C) 2017 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-do run { target c++11 } }
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ // PR libstdc++83598
+ std::regex r1(".", std::regex_constants::syntax_option_type{});
+ VERIFY(r1.flags() == std::regex_constants::syntax_option_type{});
+ std::regex r2(".", std::regex_constants::icase);
+ VERIFY(r2.flags() == std::regex_constants::icase);
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
index 80b8bf767e5..82ae40dc219 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
@@ -32,6 +32,8 @@ void test01()
std::cmatch cm;
VERIFY( cm.size() == 0 );
VERIFY( !cm.ready() );
+ VERIFY( cm.empty() );
+ VERIFY( cm.begin() == cm.end() ); // PR libstdc++/83600
}
void test02()
@@ -41,6 +43,8 @@ void test02()
std::smatch sm;
VERIFY( sm.size() == 0 );
VERIFY( !sm.ready() );
+ VERIFY( sm.empty() );
+ VERIFY( sm.begin() == sm.end() ); // PR libstdc++/83600
}
int
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
index a4f68c1fc0d..88fe6a4f54c 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
@@ -32,6 +32,8 @@ void test01()
std::wcmatch cm;
VERIFY( cm.size() == 0 );
VERIFY( !cm.ready() );
+ VERIFY( cm.empty() );
+ VERIFY( cm.begin() == cm.end() ); // PR libstdc++/83600
}
void test02()
@@ -41,6 +43,8 @@ void test02()
std::wsmatch sm;
VERIFY( sm.size() == 0 );
VERIFY( !sm.ready() );
+ VERIFY( sm.empty() );
+ VERIFY( sm.begin() == sm.end() ); // PR libstdc++/83600
}
int
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
index 9e94c4799be..dec59697163 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
@@ -28,6 +28,7 @@ void
test01()
{
bool test __attribute__((unused)) = false;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
std::error_code ec;
// Test non-existent path.
@@ -37,15 +38,19 @@ test01()
VERIFY( iter == end(iter) );
// Test empty directory.
+ ec = bad_ec;
create_directory(p, fs::current_path(), ec);
VERIFY( !ec );
+ ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test non-empty directory.
- create_directories(p / "d1/d2");
+ ec = bad_ec;
+ create_directories(p / "d1/d2", ec);
VERIFY( !ec );
+ ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
@@ -56,6 +61,7 @@ test01()
VERIFY( iter == end(iter) );
// Test inaccessible directory.
+ ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::recursive_directory_iterator(p, ec);
@@ -64,15 +70,19 @@ test01()
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
+ ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory.
+ ec = bad_ec;
permissions(p, fs::perms::owner_all, ec);
VERIFY( !ec );
+ ec = bad_ec;
permissions(p/"d1/d2", fs::perms::none, ec);
VERIFY( !ec );
+ ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
@@ -84,12 +94,14 @@ test01()
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory, skipping permission denied.
+ ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter->path() == p/"d1/d2" );
+ ec = bad_ec;
iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
VERIFY( !ec );
VERIFY( iter == end(iter) );
@@ -103,12 +115,15 @@ test02()
{
bool test __attribute__((unused)) = false;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
std::error_code ec;
const auto p = __gnu_test::nonexistent_path();
+ ec = bad_ec;
create_directories(p / "d1/d2", ec);
VERIFY( !ec );
// Test post-increment (libstdc++/71005)
+ ec = bad_ec;
auto iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
@@ -130,7 +145,7 @@ test03()
{
bool test __attribute__((unused)) = false;
- std::error_code ec;
+ std::error_code ec = make_error_code(std::errc::invalid_argument);
const auto p = __gnu_test::nonexistent_path();
create_directories(p / "longer_than_small_string_buffer", ec);
VERIFY( !ec );
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
index 66c2b3fb796..eae60a05bd4 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
@@ -50,7 +50,6 @@ test01()
VERIFY( !ec );
VERIFY( !b );
b = create_directory(p);
- VERIFY( !ec );
VERIFY( !b );
remove_all(p, ec);
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/remove.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/remove.cc
new file mode 100644
index 00000000000..7c098b4864b
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/remove.cc
@@ -0,0 +1,100 @@
+// Copyright (C) 2018 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;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
+ bool n;
+
+ n = fs::remove("", ec);
+ VERIFY( !ec ); // This seems odd, but is what the standard requires.
+ VERIFY( !n );
+
+ auto p = __gnu_test::nonexistent_path();
+ ec = bad_ec;
+ n = remove(p, ec);
+ VERIFY( !ec );
+ VERIFY( !n );
+
+ auto link = __gnu_test::nonexistent_path();
+ create_symlink(p, link); // dangling symlink
+ ec = bad_ec;
+ n = remove(link, ec);
+ VERIFY( !ec );
+ VERIFY( n );
+ VERIFY( !exists(symlink_status(link)) );
+
+ __gnu_test::scoped_file f(p);
+ create_symlink(p, link);
+ ec = bad_ec;
+ n = remove(link, ec);
+ VERIFY( !ec );
+ VERIFY( n );
+ VERIFY( !exists(symlink_status(link)) ); // The symlink is removed, but
+ VERIFY( exists(p) ); // its target is not.
+
+ ec = bad_ec;
+ n = remove(p, ec);
+ VERIFY( !ec );
+ VERIFY( n );
+ VERIFY( !exists(symlink_status(p)) );
+
+ const auto dir = __gnu_test::nonexistent_path();
+ create_directories(dir/"a/b");
+ ec.clear();
+ n = remove(dir/"a", ec);
+ VERIFY( ec );
+ VERIFY( !n );
+ VERIFY( exists(dir/"a/b") );
+
+ permissions(dir, fs::perms::none, ec);
+ if (!ec)
+ {
+ ec.clear();
+ n = remove(dir/"a/b", ec);
+ VERIFY( ec );
+ VERIFY( !n );
+ permissions(dir, fs::perms::owner_all, ec);
+ }
+
+ ec = bad_ec;
+ n = remove(dir/"a/b", ec);
+ VERIFY( !ec );
+ VERIFY( n );
+ VERIFY( !exists(dir/"a/b") );
+
+ remove(dir/"a", ec);
+ remove(dir, ec);
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc
index 57d15af9c5c..67f6e989d27 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/remove_all.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 Free Software Foundation, Inc.
+// Copyright (C) 2016-2018 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
@@ -29,19 +29,19 @@ void
test01()
{
std::error_code ec;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
std::uintmax_t n;
n = fs::remove_all("", ec);
- VERIFY( ec );
- VERIFY( n == std::uintmax_t(-1) );
+ VERIFY( !ec ); // This seems odd, but is what the TS requires.
+ VERIFY( n == 0 );
auto p = __gnu_test::nonexistent_path();
- ec.clear();
+ ec = bad_ec;
n = remove_all(p, ec);
- VERIFY( ec );
- VERIFY( n == std::uintmax_t(-1) );
+ VERIFY( !ec );
+ VERIFY( n == 0 );
- const auto bad_ec = ec;
auto link = __gnu_test::nonexistent_path();
create_symlink(p, link); // dangling symlink
ec = bad_ec;
@@ -59,7 +59,7 @@ test01()
VERIFY( !exists(symlink_status(link)) ); // The symlink is removed, but
VERIFY( exists(p) ); // its target is not.
- auto dir = __gnu_test::nonexistent_path();
+ const auto dir = __gnu_test::nonexistent_path();
create_directories(dir/"a/b/c");
ec = bad_ec;
n = remove_all(dir/"a", ec);
@@ -85,8 +85,28 @@ test01()
b2.path.clear();
}
+void
+test02()
+{
+ const auto dir = __gnu_test::nonexistent_path();
+ create_directories(dir/"a/b/c");
+ std::uintmax_t n = remove_all(dir/"a");
+ VERIFY( n == 3 );
+ VERIFY( exists(dir) );
+ VERIFY( !exists(dir/"a") );
+
+ n = remove_all(dir/"a");
+ VERIFY( n == 0 );
+ VERIFY( exists(dir) );
+
+ n = remove_all(dir);
+ VERIFY( n == 1 );
+ VERIFY( !exists(dir) );
+}
+
int
main()
{
test01();
+ test02();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
index 23d4b9c4ab3..06c48cb2020 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
@@ -44,7 +44,7 @@ test01()
if (!fs::exists("/tmp"))
return; // just give up
- std::error_code ec;
+ std::error_code ec = make_error_code(std::errc::invalid_argument);
fs::path p1 = fs::temp_directory_path(ec);
VERIFY( !ec );
VERIFY( exists(p1) );