Calling the non-const data() member on a COW string makes it "leaked",
possibly resulting in reallocating the string to ensure a unique owner.
The path::_M_split_cmpts() member parses its _M_pathname string using
string_view objects and then calls _M_pathname.data() to find the offset
of each string_view from the start of the string. However because
_M_pathname is non-const that will cause a COW string to reallocate if
it happens to be shared with another string object. This results in the
offsets calculated for each component being wrong (i.e. undefined)
because the string views no longer refer to substrings of the
_M_pathname member. The fix is to use the parse.offset(c) member which
gets the offset safely.
The bug only happens for the path(string_type&&) constructor and only
for COW strings. When constructed from an lvalue string the string's
contents are copied rather than just incrementing the refcount, so
there's no reallocation when calling the non-const data() member. The
testsuite changes check the lvalue case anyway, because we should
probably change the deep copying to just be a refcount increment (by
adding a path(const string_type&) constructor or an overload for
__effective_range(const string_type&), for COW strings only).
libstdc++-v3/ChangeLog:
PR libstdc++/99805
* src/c++17/fs_path.cc (path::_M_split_cmpts): Do not call
non-const member on _M_pathname, to avoid copy-on-write.
* testsuite/27_io/filesystem/path/decompose/parent_path.cc:
Check construction from strings that might be shared.
The _wrename function won't overwrite an existing file, so use
MoveFileEx instead. That allows renaming directories over files, which
POSIX doesn't allow, so check for that case explicitly and report an
error.
Also document the deviation from the expected behaviour, and add a test
for filesystem::rename which was previously missing.
The Filesystem TS experimental::filesystem::rename doesn't have that
extra code to handle directories correctly, so the relevant parts of the
new test are not run on Windows.
libstdc++-v3/ChangeLog:
* doc/xml/manual/status_cxx2014.xml: Document implementation
specific properties of std::experimental::filesystem::rename.
* doc/xml/manual/status_cxx2017.xml: Document implementation
specific properties of std::filesystem::rename.
* doc/html/*: Regenerate.
* src/c++17/fs_ops.cc (fs::rename): Implement correct behaviour
for directories on Windows.
* src/filesystem/ops-common.h (__gnu_posix::rename): Use
MoveFileExW on Windows.
* testsuite/27_io/filesystem/operations/rename.cc: New test.
* testsuite/experimental/filesystem/operations/rename.cc: New test.
The std::emit_on_flush manipulator depends on dynamic_cast, so fails
without RTTI.
The std::async code can't catch a forced_unwind exception when RTTI is
disabled, so it can't rethrow it either, and the test aborts.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_ostream/emit/1.cc: Expect test to fail
if -fno-rtti is used.
* testsuite/30_threads/async/forced_unwind.cc: Expect test
to abort if -fno-rtti is used.
libstdc++-v3/ChangeLog:
* testsuite/27_io/filesystem/operations/remove_all.cc: Remove
test directory after making it writable again.
* testsuite/experimental/filesystem/operations/remove_all.cc:
Likewise.
On targets with 32-bit poitners these tests do extra work, so give them
longer to run.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_istream/ignore/char/94749.cc: Add
dg-timeout-factor for ilp32 targets.
* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc:
Likewise.
This adds the manipulators for use with basic_osyncstream. In order to
detect when an arbitrary basic_ostream<C,T> is the base class of a
basic_syncbuf<C,T,A> object, introduce a new intermediate base class
that stores the data members. The new base class stores a pointer and
two bools, which wastes (sizeof(void*) - 2) bytes of padding. It would
be possible to use the two least significant bits of the pointer for the
two bools, at least for targets where alignof(basic_streambuf) > 2, but
that's left as a possible change for a future date.
Also define basic_syncbuf::overflow to override the virtual function in
the base class, so that single characters can be inserted into the
stream buffer. Previously the default basic_streambuf::overflow
implementation was used, which drops the character on the floor.
libstdc++-v3/ChangeLog:
* include/std/ostream (__syncbuf_base): New class template.
(emit_on_flush, noemit_on_flush, flush_emit): New manipulators.
* include/std/syncstream (basic_syncbuf): Derive from
__syncbuf_base instead of basic_streambuf.
(basic_syncbuf::operator=): Remove self-assignment check.
(basic_syncbuf::swap): Remove self-swap check.
(basic_syncbuf::emit): Do not skip pubsync() call if sequence
is empty.
(basic_syncbuf::sync): Remove no-op pubsync on stringbuf.
(basic_syncbuf::overflow): Define override.
* testsuite/27_io/basic_syncstream/basic_ops/1.cc: Test
basic_osyncstream::put(char_type).
* testsuite/27_io/basic_ostream/emit/1.cc: New test.
- Add a missing 'explicit' to a basic_stringbuf constructor.
- Set up the get/put area pointers in the constructor from strings using
different allocator types.
- Remove public basic_stringbuf::__sv_type alias.
- Do not construct temporary basic_string objects with a
default-constructed allocator.
Also, change which basic_string constructor is used, as a minor
compile-time optimization. Constructing from a basic_string_view
requires more work from the compiler, so just use a pointer and length.
libstdc++-v3/ChangeLog:
* include/std/sstream (basic_stringbuf(const allocator_type&):
Add explicit.
(basic_stringbuf(const basic_string<C,T,SA>&, openmode, const A&)):
Call _M_stringbuf_init. Construct _M_string from pointer and length
to avoid constraint checks for string view.
(basic_stringbuf::view()): Make __sv_type alias local to the
function.
(basic_istringstream(const basic_string<C,T,SA>&, openmode, const A&)):
Pass string to _M_streambuf instead of constructing a temporary
with the wrong allocator.
(basic_ostringstream(const basic_string<C,T,SA>&, openmode, const A&)):
Likewise.
(basic_stringstream(const basic_string<C,T,SA>&, openmode, const A&)):
Likewise.
* src/c++20/sstream-inst.cc: Use string_view and wstring_view
typedefs in explicit instantiations.
* testsuite/27_io/basic_istringstream/cons/char/1.cc: Add more
tests for constructors.
* testsuite/27_io/basic_ostringstream/cons/char/1.cc: Likewise.
* testsuite/27_io/basic_stringbuf/cons/char/1.cc: Likewise.
* testsuite/27_io/basic_stringbuf/cons/char/2.cc: Likewise.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc: Likewise.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_stringstream/cons/char/1.cc: Likewise.
These tests were not being run when -D_GLIBCXX_USE_CXX11_ABI=0 was added
to the test flags, but they actually work OK with the old string.
libstdc++-v3/ChangeLog:
* testsuite/21_strings/basic_string/allocator/char/minimal.cc:
Do not require cxx11-abi effective target.
* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc:
Likewise.
* testsuite/27_io/basic_fstream/cons/base.cc: Likewise.
The new constructors that C++11 added to std::ios_base::failure were
missing for the old ABI. This adds them, but just ignores the
std::error_code argument (because there's nowhere to store it).
This also adds a code() member, which should be provided by the
std::system_error base class, but that base class isn't present in the
old ABI.
This allows the old ios::failure to be used in code that expects the new
API, although with reduced functionality.
libstdc++-v3/ChangeLog:
* include/bits/ios_base.h (ios_base::failure): Add constructors
takeing error_code argument. Add code() member function.
* testsuite/27_io/ios_base/failure/cxx11.cc: Allow test to
run for the old ABI but do not check for derivation from
std::system_error.
* testsuite/27_io/ios_base/failure/error_code.cc: New test.
libstdc++-v3/ChangeLog:
PR libstdc++/97167
* src/c++17/fs_path.cc (path::_Parser::root_path()): Check
for empty string before inspecting the first character.
* testsuite/27_io/filesystem/path/append/source.cc: Append
empty string_view to path.
Back in 2017 I removed these prehistoric members (which were deprecated
since C++98) for C++17 mode. But I didn't add deprecated attributes to
most of them, so users didn't get any warning they would be going away.
Apparently some poor souls do actually use some of these names, and so
now that GCC 11 defaults to -std=gnu++17 some code has stopped
compiling.
This adds deprecated attributes to them, so that C++98/03/11/14 code
will get a warning if it uses them. I'll also backport this to the
release branches so that users can find out about the deprecation before
they start using C++17.
In order to give deprecated warnings even in C++98 mode this patch makes
_GLIBCXX_DEPRECATED work even for C++98, adds _GLIBCXX11_DEPRECATED for
the old meaning of _GLIBCXX_DEPRECATED, and adds new macros such as
_GLIBCXX_DEPRECATED_SUGGEST for suggesting alternatives to deprecated
features.
libstdc++-v3/ChangeLog:
* include/bits/c++config (_GLIBCXX_DEPRECATED): Define for all
standard modes.
(_GLIBCXX_DEPRECATED_SUGGEST): New macro for "use 'foo' instead"
message in deprecated warnings.
(_GLIBCXX11_DEPRECATED, _GLIBCXX11_DEPRECATED_SUGGEST): New
macros for marking features derpecated in C++11.
(_GLIBCXX17_DEPRECATED_SUGGEST, _GLIBCXX20_DEPRECATED_SUGGEST):
New macros.
* include/backward/auto_ptr.h (auto_ptr_ref, auto_ptr<void>):
Use _GLIBCXX11_DEPRECATED instead of _GLIBCXX_DEPRECATED.
(auto_ptr): Use _GLIBCXX11_DEPRECATED_SUGGEST.
* include/backward/binders.h (binder1st, binder2nd): Likewise.
* include/bits/ios_base.h (io_state, open_mode, seek_dir)
(streampos, streamoff): Use _GLIBCXX_DEPRECATED_SUGGEST.
* include/std/streambuf (stossc): Replace C++11 attribute
with _GLIBCXX_DEPRECATED_SUGGEST.
* include/std/type_traits (__is_nullptr_t): Use
_GLIBCXX_DEPRECATED_SUGGEST instead of _GLIBCXX_DEPRECATED.
* testsuite/27_io/types/1.cc: Check for deprecated warnings.
Also check for io_state, open_mode and seek_dir typedefs.
Similar to the bugs I fixed recently in istream::ignore, we incorrectly
set eofbit too often in operator>>(istream&, string&) and
operator>>(istream&. char(&)[N]).
We should only set eofbit if we reach EOF but would have kept going
otherwise. If we've already extracted the maximum number of characters
(whether that's because of the buffer size or the istream's width())
then we should not set eofbit.
libstdc++-v3/ChangeLog:
* include/bits/basic_string.tcc
(operator>>(basic_istream&, basic_string&)): Do not set eofbit
if extraction stopped after in.width() characters.
* src/c++98/istream-string.cc (operator>>(istream&, string&)):
Likewise.
* include/bits/istream.tcc (__istream_extract): Do not set
eofbit if extraction stopped after n-1 characters.
* src/c++98/istream.cc (__istream_extract): Likewise.
* testsuite/21_strings/basic_string/inserters_extractors/char/13.cc: New test.
* testsuite/21_strings/basic_string/inserters_extractors/wchar_t/13.cc: New test.
* testsuite/27_io/basic_istream/extractors_character/char/5.cc: New test.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/5.cc: New test.
This adjusts the overflow prevention added to operator>> so that we can
distinguish "unknown size" from "zero size", and avoid writing anything
at all in to zero sized buffers.
This also removes the incorrect comment saying extraction stops at a
null byte.
libstdc++-v3/ChangeLog:
* include/std/istream (operator>>(istream&, char*)): Add
attributes to get warnings for pointers that are null or known
to point to the end of a buffer. Request upper bound from
__builtin_object_size check and handle zero-sized buffer case.
(operator>>(istream&, signed char))
(operator>>(istream&, unsigned char*)): Add attributes.
* testsuite/27_io/basic_istream/extractors_character/char/overflow.cc:
Check extracting into the middle of a buffer.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/overflow.cc: New test.
P0487R1 resolved LWG 2499 for C++20 by removing the operator>> overloads
that have high risk of buffer overflows. They were replaced by
equivalents that only accept a reference to an array, and so can
guarantee not to write past the end of the array.
In order to support both the old and new functionality, this patch
introduces a new overloaded __istream_extract function which takes a
maximum length. The new operator>> overloads use the array size as the
maximum length. The old overloads now use __builtin_object_size to
determine the available buffer size if available (which requires -O2) or
use numeric_limits<streamsize>::max()/sizeof(char_type) otherwise. This
is a change in behaviour, as the old overloads previously always used
numeric_limits<streamsize>::max(), without considering sizeof(char_type)
and without attempting to prevent overflows.
Because they now do little more than call __istream_extract, the old
operator>> overloads are very small inline functions. This means there
is no advantage to explicitly instantiating them in the library (in fact
that would prevent the __builtin_object_size checks from ever working).
As a result, the explicit instantiation declarations can be removed from
the header. The explicit instantiation definitions are still needed, for
backwards compatibility with existing code that expects to link to the
definitions in the library.
While working on this change I noticed that src/c++11/istream-inst.cc
has the following explicit instantiation definition:
template istream& operator>>(istream&, char*);
This had no effect (and so should not have been present in that file),
because there was an explicit specialization declared in <istream> and
defined in src/++98/istream.cc. However, this change removes the
explicit specialization, and now the explicit instantiation definition
is necessary to ensure the symbol gets defined in the library.
libstdc++-v3/ChangeLog:
* config/abi/pre/gnu.ver (GLIBCXX_3.4.29): Export new symbols.
* include/bits/istream.tcc (__istream_extract): New function
template implementing both of operator>>(istream&, char*) and
operator>>(istream&, char(&)[N]). Add explicit instantiation
declaration for it. Remove explicit instantiation declarations
for old function templates.
* include/std/istream (__istream_extract): Declare.
(operator>>(basic_istream<C,T>&, C*)): Define inline and simply
call __istream_extract.
(operator>>(basic_istream<char,T>&, signed char*)): Likewise.
(operator>>(basic_istream<char,T>&, unsigned char*)): Likewise.
(operator>>(basic_istream<C,T>&, C(7)[N])): Define for LWG 2499.
(operator>>(basic_istream<char,T>&, signed char(&)[N])):
Likewise.
(operator>>(basic_istream<char,T>&, unsigned char(&)[N])):
Likewise.
* include/std/streambuf (basic_streambuf): Declare char overload
of __istream_extract as a friend.
* src/c++11/istream-inst.cc: Add explicit instantiation
definition for wchar_t overload of __istream_extract. Remove
explicit instantiation definitions of old operator>> overloads
for versioned-namespace build.
* src/c++98/istream.cc (operator>>(istream&, char*)): Replace
with __istream_extract(istream&, char*, streamsize).
* testsuite/27_io/basic_istream/extractors_character/char/3.cc:
Do not use variable-length array.
* testsuite/27_io/basic_istream/extractors_character/char/4.cc:
Do not run test for C++20.
* testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc:
Do not test writing to pointers for C++20.
* testsuite/27_io/basic_istream/extractors_character/char/9826.cc:
Use array instead of pointer.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/3.cc:
Do not use variable-length array.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/4.cc:
Do not run test for C++20.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/9555-ic.cc:
Do not test writing to pointers for C++20.
* testsuite/27_io/basic_istream/extractors_character/char/lwg2499.cc:
New test.
* testsuite/27_io/basic_istream/extractors_character/char/lwg2499_neg.cc:
New test.
* testsuite/27_io/basic_istream/extractors_character/char/overflow.cc:
New test.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/lwg2499.cc:
New test.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/lwg2499_neg.cc:
New test.
Similar to the recent changes to basic_istream::ignore, this change
ensures that _M_gcount doesn't overflow when extracting characters and
inserting them into another streambuf.
The solution used here is to use unsigned long long for the count. We
assume that the number of characters extracted won't exceed the maximum
value for that type, but even if it does we avoid any undefined
behaviour.
libstdc++-v3/ChangeLog:
* include/bits/istream.tcc
(basic_istream::get(__streambuf_type&, char_type): Use unsigned
long long for counter and check if it would overflow _M_gcount.
* testsuite/27_io/basic_istream/get/char/lwg3464.cc: New test.
* testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc: New test.
My previous fix for PR 94749 did fix the reported case, so that the next
character is not discarded if it happens to equal the delimiter when __n
characters have already been read. But it introduced a new bug, which is
that the delimiter character would *not* be discarded if the number of
characters discarded is numeric_limits<streamsize>::max() or more before
reaching the delimiter.
The new bug happens because I changed the code to check _M_gcount < __n.
But when __n == numeric_limits<streamsize>::max() that is false, and so
we don't discard the delimiter. It's not sufficient to check for the
delimiter when the __large_ignore condition is true, because there's an
edge case where the delimiter is reached when _M_gcount == __n and so
we break out of the loop without setting __large_ignore.
PR 96161 is a similar bug to the original PR 94749 report, where eofbit
is set after discarding __n characters if there happen to be no more
characters in the stream.
This patch fixes both cases (and the regression) by checking different
conditions for the __n == max case and the __n < max case. For the
former case, we know that we must have either reached the delimiter or
EOF, and the value of _M_gcount doesn't matter (except to avoid integer
overflow). For the latter case we need to check _M_gcount first and only
set eofbit or discard the delimiter if it didn't reach __n. For the
latter case overflow can't happen because _M_gcount <= __n < max.
libstdc++-v3/ChangeLog:
PR libstdc++/94749
PR libstdc++/96161
* include/bits/istream.tcc (basic_istream::ignore(streamsize))
[n == max]: Check overflow conditions on _M_gcount. Rely on
the fact that either EOF or the delimiter was reached.
[n < max]: Check _M_gcount < n before checking for EOF or
delimiter.
(basic_istream::ignore(streamsize, char_type): Likewise.
* src/c++98/compatibility.cc (istream::ignore(streamsize))
(wistream::ignore(streamsize)): Likewise.
* src/c++98/istream.cc (istream::ignore(streamsize, char_type))
(wistream::ignore(streamsize, char_type)): Likewise.
* testsuite/27_io/basic_istream/ignore/char/94749.cc: Check that
delimiter is discarded if the number of characters ignored
doesn't fit in streamsize.
* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc:
Likewise.
* testsuite/27_io/basic_istream/ignore/char/96161.cc: New test.
* testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc: New test.
This test checks a conversion which only exists in C++98 and won't
compile since C++11. It uses { dg-options "-std=gnu++98" } so that it is
explicitly run in C++98 mode. This change also adds a target selector so
that the test will be skipped if the dg-options directive is filtered
out or overridden.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_ios/conv/voidptr.cc: Add c++98_only
target selector.
These tests verify that including C++11 headers fails to compile in
C++98 mode. They use { dg-options "-std=gnu++98" } so that they are
explicitly run in C++98 mode. This change also adds a target selector so
that the tests will be skipped even if the dg-options directive is
filtered out or overridden. This is in preparation for a desired future
change where tests do not use -std options, so that they can be tested
with e.g. --target_board=unix\"{-std=gnu++17,-std=gnu++20}\"
In some cases the dg-options and dg-do directives need to be reordered,
so that the -std=gnu++98 option is already added to the options before
the target selector is checked.
libstdc++-v3/ChangeLog:
* testsuite/18_support/headers/cstdalign/std_c++0x_neg.cc: Add
c++98_only target selector.
* testsuite/18_support/headers/cstdbool/std_c++0x_neg.cc:
Likewise.
* testsuite/18_support/headers/cstdint/std_c++0x_neg.cc:
Likewise.
* testsuite/18_support/headers/new/synopsis_cxx98.cc: Likewise.
* testsuite/19_diagnostics/headers/system_error/std_c++0x_neg.cc:
Likewise.
* testsuite/20_util/headers/type_traits/std_c++0x_neg.cc:
Likewise.
* testsuite/23_containers/headers/array/std_c++0x_neg.cc:
Likewise.
* testsuite/23_containers/headers/tuple/std_c++0x_neg.cc:
Likewise.
* testsuite/23_containers/headers/unordered_map/std_c++0x_neg.cc:
Likewise.
* testsuite/23_containers/headers/unordered_set/std_c++0x_neg.cc:
Likewise.
* testsuite/26_numerics/headers/ccomplex/std_c++0x_neg.cc:
Likewise.
* testsuite/26_numerics/headers/cfenv/std_c++0x_neg.cc:
Likewise.
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c++98.cc:
Likewise.
* testsuite/26_numerics/headers/ctgmath/std_c++0x_neg.cc:
Likewise.
* testsuite/26_numerics/headers/random/std_c++0x_neg.cc:
Likewise.
* testsuite/27_io/headers/cinttypes/std_c++0x_neg.cc: Likewise.
* testsuite/28_regex/headers/regex/std_c++0x_neg.cc: Likewise.
* testsuite/29_atomics/headers/atomic/std_c++0x_neg.cc:
Likewise.
* testsuite/30_threads/headers/condition_variable/std_c++0x_neg.cc:
Likewise.
* testsuite/30_threads/headers/future/std_c++0x_neg.cc:
Likewise.
* testsuite/30_threads/headers/mutex/std_c++0x_neg.cc: Likewise.
* testsuite/30_threads/headers/thread/std_c++0x_neg.cc:
Likewise.
The current code assumes that if the next character in the stream is
equal to the delimiter then we stopped because we saw that delimiter,
and so discards it. But in the testcase for the PR we stop because we
reached the maximum number of characters, and it's coincidence that the
next character equals the delimiter. We should not discard the next
character in that case.
The fix is to check that we haven't discarded __n characters already,
instead of checking whether the next character equals __delim. Because
we've already checked for EOF, if we haven't discarded __n yet then we
know we stopped because we saw the delimiter. On the other hand, if the
next character is the delimiter we don't know if that's why we stopped.
PR libstdc++/94749
* include/bits/istream.tcc (basic_istream::ignore(streamsize, CharT)):
Only discard an extra character if we didn't already reach the
maximum number.
* src/c++98/istream.cc (istream::ignore(streamsiz, char))
(wistream::ignore(streamsize, wchar_t)): Likewise.
* testsuite/27_io/basic_istream/ignore/char/94749.cc: New test.
* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc: New test.
This replaces the filesystem::__detail::_Path SFINAE helper with two
separate helpers, _Path and _Path2. This avoids having one helper which
tries to check two different sets of requirements.
The _Path helper now uses variable templates instead of a set of
overloaded functions to detect specializations of basic_string or
basic_string_view.
The __not_<is_void<remove_pointer_t<_Tp1>> check is not necessary in
C++20 because iterator_traits<void*> is now empty. For C++17 replace
that check with a __safe_iterator_traits helper with partial
specializations for void pointers.
Finally, the __is_encoded_char check no longer uses remove_const_t,
which means that iterators with a const value_type will no longer be
accepted as arguments for path creation. Such iterators resulted in
undefined behaviour anyway, so it's still conforming to reject them in
the constraint checks.
* include/bits/fs_path.h (filesystem::__detail::__is_encoded_char):
Replace alias template with variable template. Don't remove const.
(filesystem::__detail::__is_path_src): Replace overloaded function
template with variable template and specializations.
(filesystem::__detail::__is_path_iter_src): Replace alias template
with class template.
(filesystem::__detail::_Path): Use __is_path_src. Remove support for
iterator pairs.
(filesystem::__detail::_Path2): New alias template for checking
InputIterator requirements.
(filesystem::__detail::__constructible_from): Remove.
(filesystem::path): Replace _Path<Iter, Iter> with _Path2<Iter>.
* testsuite/27_io/filesystem/path/construct/80762.cc: Check with two
constructor arguments of void and void* types.
It's not possible to construct a path::string_type from an allocator of
a different type. Create the correct specialization of basic_string, and
adjust path::_S_str_convert to use a basic_string_view so that it is
independent of the allocator type.
PR libstdc++/94242
* include/bits/fs_path.h (path::_S_str_convert): Replace first
parameter with basic_string_view so that strings with different
allocators can be accepted.
(path::generic_string<C,T,A>()): Use basic_string object that uses the
right allocator type.
* testsuite/27_io/filesystem/path/generic/94242.cc: New test.
* testsuite/27_io/filesystem/path/generic/generic_string.cc: Improve
test coverage.
The filesystem::path::operator+= and filesystem::path::concat functions
operate directly on the native format of the path and so can cause a
path to mutate to a completely different type.
For Windows combining a filename "x" with a filename ":" produces a
root-name "x:". Similarly, a Cygwin root-directory "/" combined with a
root-directory and filename "/x" produces a root-name "//x".
Before this patch the implemenation didn't support those kind of
mutations, assuming that concatenating two filenames would always
produce a filename and concatenating with a root-dir would still have a
root-dir.
This patch fixes it simply by checking for the problem cases and
creating a new path by re-parsing the result of the string
concatenation. This is slightly suboptimal because the argument has
already been parsed if it's a path, but more importantly it doesn't
reuse any excess capacity that the path object being modified might
already have allocated. That can be fixed later though.
PR libstdc++/94063
* src/c++17/fs_path.cc (path::operator+=(const path&)): Add kluge to
handle concatenations that change the type of the first component.
(path::operator+=(basic_string_view<value_type>)): Likewise.
* testsuite/27_io/filesystem/path/concat/94063.cc: New test.
The checks for PR 93244 don't actually pass on Windows (which is the
target where the bug is present) because of a different bug, PR 94063.
This adjusts the tests to not be affected by 94063 so that they verify
that 93244 was fixed.
PR libstdc++/93244
* testsuite/27_io/filesystem/path/generic/generic_string.cc: Adjust
test to not fail due to PR 94063.
* testsuite/27_io/filesystem/path/generic/utf.cc: Likewise.
* testsuite/27_io/filesystem/path/generic/wchar_t.cc: Likewise.
There's a -Wunused-but-set-variable warning in operations/all.cc which
can be fixed with [[maybe_unused]].
The statements in operations/copy.cc give -Wunused-value warnings. I
think I meant to use |= rather than !=.
And operations/file_size.cc gets -Wsign-compare warnings.
* testsuite/27_io/filesystem/operations/all.cc: Mark unused variable.
* testsuite/27_io/filesystem/operations/copy.cc: Fix typo.
* testsuite/experimental/filesystem/operations/copy.cc: Likewise.
* testsuite/27_io/filesystem/operations/file_size.cc: Use correct type
for return value, and in comparison.
* testsuite/experimental/filesystem/operations/file_size.cc: Likewise.
These tests were failing on XFS because it doesn't support setting file
timestamps past 2038, so the expected overflow when reading back a huge
timestamp into a file_time_type didn't happen.
Additionally, the std::filesystem::file_time_type::clock has an
epoch that is out of range of 32-bit time_t so testing times around that
epoch may also fail.
This fixes the tests to give up gracefully if the filesystem doesn't
support times that can't be represented in 32-bit time_t.
* testsuite/27_io/filesystem/operations/last_write_time.cc: Fixes for
filesystems that silently truncate timestamps.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Likewise.
Padding in mbstate_t objects may get the memcmp to fail.
Attempt to avoid the failure with zero initialization.
for libstdc++-v3/ChangeLog
* testsuite/27_io/fpos/mbstate_t/1.cc: Zero-init mbstate_t.
PR libstdc++/93244
* include/bits/fs_path.h (path::generic_string<C,A>)
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Convert root-dir to forward-slash.
* testsuite/27_io/filesystem/path/generic/generic_string.cc: Check
root-dir is converted to forward slash in generic pathname.
* testsuite/27_io/filesystem/path/generic/utf.cc: New test.
* testsuite/27_io/filesystem/path/generic/wchar_t.cc: New test.
When recursing into a directory, any errors that occur while removing a
directory entry are ignored, because the subsequent increment of the
directory iterator clears the error_code object.
This fixes that bug by checking the result of each recursive operation
before incrementing. This is a change in observable behaviour, because
previously other directory entries would still be removed even if one
(or more) couldn't be removed due to errors. Now the operation stops on
the first error, which is what the code intended to do all along. The
standard doesn't specify what happens in this case (because the order
that the entries are processed is unspecified anyway).
It also improves the error reporting so that the name of the file that
could not be removed is included in the filesystem_error exception. This
is done by introducing a new helper type for reporting errors with
additional context and a new function that uses that type. Then the
overload of std::filesystem::remove_all that throws an exception can use
the new function to ensure any exception contains the additional
information.
For std::experimental::filesystem::remove_all just fix the bug where
errors are ignored.
PR libstdc++/93201
* src/c++17/fs_ops.cc (do_remove_all): New function implementing more
detailed error reporting for remove_all. Check result of recursive
call before incrementing iterator.
(remove_all(const path&), remove_all(const path&, error_code&)): Use
do_remove_all.
* src/filesystem/ops.cc (remove_all(const path&, error_code&)): Check
result of recursive call before incrementing iterator.
* testsuite/27_io/filesystem/operations/remove_all.cc: Check errors
are reported correctly.
* testsuite/experimental/filesystem/operations/remove_all.cc: Likewise.
From-SVN: r280014
When concatenating a path ending in a root-directory onto another path,
we added an empty filename to the end of the path twice, but only
reserved space for one. That meant the second write went past the end of
the allocated buffer.
PR libstdc++/92853
* src/c++17/fs_path.cc (filesystem::path::operator+=(const path&)):
Do not process a trailing directory separator twice.
* testsuite/27_io/filesystem/path/concat/92853.cc: New test.
* testsuite/27_io/filesystem/path/concat/path.cc: Test more cases.
From-SVN: r279110
New tests
This patch adds new tests to validate new deleted overloads of wchar_t,
char8_t, char16_t, and char32_t for ordinary and wide formatted character and
string ostream inserters.
Additionally, new tests are added to validate invocations of u8path with
sequences of char8_t for both the C++17 and filesystem TS implementations.
2019-11-29 Tom Honermann <tom@honermann.net>
New tests
* testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc:
New test to validate deleted overloads of character and string
inserters for narrow ostreams.
* testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc:
New test to validate deleted overloads of character and string
inserters for wide ostreams.
* testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc: New test
to validate u8path invocations with sequences of char8_t.
* testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc:
New test to validate u8path invocations with sequences of char8_t.
From-SVN: r278858
Updates to existing tests
This patch updates existing tests to validate the new value for the
__cpp_lib_char8_t feature test macros and to exercise u8path factory
function invocations with std::string, std::string_view, and interator
pair arguments.
2019-11-29 Tom Honermann <tom@honermann.net>
Updates to existing tests
* testsuite/experimental/feat-char8_t.cc: Updated the expected
__cpp_lib_char8_t feature test macro value.
* testsuite/27_io/filesystem/path/factory/u8path.cc: Added testing of
u8path invocation with std::string, std::string_view, and iterators
thereof.
* testsuite/experimental/filesystem/path/factory/u8path.cc: Added
testing of u8path invocation with std::string, std::string_view, and
iterators thereof.
From-SVN: r278857