This was recently approved for C++26 at the Tokyo meeting. As suggested
by Stephan T. Lavavej, I'm defining it as an extension for C++23 mode
(when std::print and std::prinln were first added) rather than as a new
C++26 feature. Both MSVC and libc++ have agreed to do this too.
libstdc++-v3/ChangeLog:
* include/std/ostream (println(ostream&)): Define new overload.
* include/std/print (println(FILE*), println()): Likewise.
* testsuite/27_io/basic_ostream/print/2.cc: New test.
* testsuite/27_io/print/1.cc: Remove unused header.
* testsuite/27_io/print/3.cc: New test.
A negative delim value passed to std::istream::ignore can never match
any character in the stream, because the comparison is done using
traits_type::eq_int_type(sb->sgetc(), delim) and sgetc() never returns
negative values (except at EOF). The optimized version of ignore for the
std::istream specialization uses traits_type::find to locate the delim
character in the streambuf, which _can_ match a negative delim on
platforms where char is signed, but then we do another comparison using
eq_int_type which fails. The code then keeps looping forever, with
traits_type::find locating the character and traits_type::eq_int_type
saying it's not a match, so traits_type::find is used again and finds
the same character again.
A possible fix would be to check with eq_int_type after a successful
find, to see whether we really have a match. However, that would be
suboptimal since we know that a negative delimiter will never match
using eq_int_type. So a better fix is to adjust the check at the top of
the function that handles delim==eof(), so that we treat all negative
delim values as equivalent to EOF. That way we don't bother using find
to search for something that will never match with eq_int_type.
The version of ignore in the primary template doesn't need a change,
because it doesn't use traits_type::find, instead characters are
extracted one-by-one and always matched using eq_int_type. That avoids
the inconsistency between find and eq_int_type. The specialization for
std::wistream does use traits_type::find, but traits_type::to_int_type
is equivalent to an implicit conversion from wchar_t to wint_t, so
passing a wchar_t directly to ignore without using to_int_type works.
libstdc++-v3/ChangeLog:
PR libstdc++/93672
* src/c++98/istream.cc (istream::ignore(streamsize, int_type)):
Treat all negative delimiter values as eof().
* testsuite/27_io/basic_istream/ignore/char/93672.cc: New test.
* testsuite/27_io/basic_istream/ignore/wchar_t/93672.cc: New
test.
The std/time/year_month_day/io.cc test assumes that %x in the fr_FR
locale is %d/%m/%Y but on FreeBSD it is %d.%m.%Y instead. Make the test
PASS for either format.
Similarly, 27_io/manipulators/extended/get_time/char/2.cc expects that
%a in the de_DE locale is "Di" but on FreeBSD it's "Di." with a trailing
period. Adjust the input string to be "1971 Di." instead of "Di 1971"
and that way if %a doesn't expect the trailing '.' it simply won't
extract it from the stream.
This fixes:
FAIL: std/time/year_month_day/io.cc -std=gnu++20 execution test
FAIL: 27_io/manipulators/extended/get_time/char/2.cc -std=gnu++17 execution test
libstdc++-v3/ChangeLog:
* testsuite/27_io/manipulators/extended/get_time/char/2.cc:
Adjust input string so that it matches %a with or without a
trailing period.
* testsuite/std/time/year_month_day/io.cc: Adjust expected
format for %x in the fr_FR locale.
Adjust expected errors or skip tests as UNSUPPORTED if -fno-char8_t is
used in the test flags.
libstdc++-v3/ChangeLog:
* testsuite/20_util/integer_comparisons/equal_neg.cc: Use
no-opts selector for errors that depend on -fchar8_t.
* testsuite/20_util/integer_comparisons/greater_equal_neg.cc:
Likewise.
* testsuite/20_util/integer_comparisons/greater_neg.cc:
Likewise.
* testsuite/20_util/integer_comparisons/in_range_neg.cc:
Likewise.
* testsuite/20_util/integer_comparisons/less_equal_neg.cc:
Likewise.
* testsuite/20_util/integer_comparisons/less_neg.cc: Likewise.
* testsuite/20_util/integer_comparisons/not_equal_neg.cc:
Likewise.
* testsuite/21_strings/basic_string/hash/hash_char8_t.cc: Skip
if -fno-char8_t is used.
* testsuite/21_strings/headers/cuchar/functions_std_cxx20.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc:
Likewise.
* testsuite/27_io/filesystem/path/factory/u8path-depr.cc: Use
char for u8 literal if char8_t is not available.
* testsuite/27_io/headers/iosfwd/synopsis.cc: Check
__cpp_char8_t.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomics/headers/atomic/types_std_c++20_neg.cc:
Remove check for _GLIBCXX_USE_CHAR8_T.
The bitwise operators for combining bitmask types such as std::launch
are not consistently annotated with noexcept, constexpr, and nodiscard.
This is the subject of LWG 3977, although the proposed resolution
doesn't work. We can make the changes in libstdc++ anyway though.
libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h (operator|, operator&): Add
noexcept.
* include/bits/fs_fwd.h (operator&, operator|, operator^)
(operator~): Add nodiscard to overloads for copy_options, perms,
perm_options, and directory_options.
* include/bits/ios_base.h (operator&, operator|, operator^)
(operator~): Add nodiscard and noexcept to overloads for
_Ios_Fmtflags, _Ios_Openmode, and _Ios_Iostate.
(operator|=, operator&=, operator^=): Add constexpr for C++14.
* include/bits/regex_constants.h (operator&, operator|, operator^)
(operator~): Add nodiscard and noexcept to overloads for
syntax_option_type and match_flag_type.
(operator|=, operator&=, operator^=): Add noexcept.
* include/std/charconv (operator&, operator|, operator^)
(operator~): Add nodiscard to overloads for chars_format.
* include/std/future (operator&, operator|, operator^)
(operator~): Add nodiscard for overloads for launch.
(operator&=, operator|=, operator^=): Add constexpr for C++14.
* include/experimental/bits/fs_fwd.h (operator&, operator|)
(operator^, operator~): Add nodiscard to overloads for
copy_options, perms, and directory_options.
* testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc:
Add dg-warning for nodiscard warnings.
* testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc:
Likewise.
* testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc:
Likewise.
* testsuite/27_io/filesystem/operations/bitmask_types.cc:
New test.
The standard requires an exception if std::print fails to write to a
FILE*. When writing to a std::ostream, failure to format the arguments
doesn't affect the stream state, but failure to write to the streadm
sets badbit.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_ostream/print/1.cc: Check error
handling.
* testsuite/27_io/print/1.cc: Likewise.
Cygwin should use std::fwrite, not WriteConsoleW. And the -lstdc++exp
library is only needed when running the tests on *-*-mingw*.
libstdc++-v3/ChangeLog:
* include/std/ostream (vprint_unicode) [__CYGWIN__]: Use POSIX
code path for Cygwin instead of Windows.
* include/std/print (vprint_unicode) [__CYGWIN__]: Likewise.
* testsuite/27_io/basic_ostream/print/1.cc: Only add -lstdc++exp
for *-*-mingw* targets.
* testsuite/27_io/print/1.cc: Likewise.
This patch made std::filesystem::equivalent correctly throw an exception
when either path does not exist as per [fs.op.equivalent]/4.
PR libstdc++/113250
libstdc++-v3/ChangeLog:
* src/c++17/fs_ops.cc (fs::equivalent): Use || instead of &&.
* src/filesystem/ops.cc (fs::equivalent): Likewise.
* testsuite/27_io/filesystem/operations/equivalent.cc: Handle
error codes.
* testsuite/experimental/filesystem/operations/equivalent.cc:
Likewise.
Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* src/c++23/print.cc (__write_to_terminal) [_WIN32]: If handle
does not refer to the console then just write to it using normal
file I/O.
* testsuite/27_io/print/2.cc (as_printed_to_terminal): Print
error message on failure.
(test_utf16_transcoding): Adjust for as_printed_to_terminal
modifying its argument.
Tim Song pointed out that although std::print behaves as a formatted
output function, it does "determine padding" using the stream's flags.
libstdc++-v3/ChangeLog:
* include/std/ostream (vprint_nonunicode, vprint_unicode): Do
not insert padding.
* testsuite/27_io/basic_ostream/print/1.cc: Adjust expected
behaviour.
This adds the C++23 std::print functions, which use std::format to write
to a FILE stream or std::ostream (defaulting to stdout).
The new extern symbols are in the libstdc++exp.a archive, so we aren't
committing to stable symbols in the DSO yet. There's a UTF-8 validating
and transcoding function added by this change. That can certainly be
optimized, but it's internal to libstdc++exp.a so can be tweaked later
at leisure.
Currently the external symbols work for all targets, but are only
actually used for Windows, where it's necessary to transcode to UTF-16
to write to the console. The standard seems to encourage us to also
diagnose invalid UTF-8 for non-Windows targets when writing to a
terminal (and only when writing to a terminal), but I'm reliably
informed that that wasn't the intent of the wording. Checking for
invalid UTF-8 sequences only needs to happen for Windows, which is good
as checking for a terminal requires a call to isatty, and on Linux that
uses an ioctl syscall, which would make std::print ten times slower!
Testing the std::print behaviour is difficult if it depends on whether
the output stream is connected to a Windows console or not, as we can't
(as far as I know) do that non-interactively in DejaGNU. One of the new
tests uses the internal __write_to_terminal function directly. That
allows us to verify its UTF-8 error handling on POSIX targets, even
though that's not actually used by std::print. For Windows, that
__write_to_terminal function transcodes to UTF-16 but then uses
WriteConsoleW which fails unless it really is writing to the console.
That means the 27_io/print/2.cc test FAILs on Windows. The UTF-16
transcoding has been manually tested using mingw-w64 and Wine, and
appears to work.
libstdc++-v3/ChangeLog:
PR libstdc++/107760
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/version.def (__cpp_lib_print): Define.
* include/bits/version.h: Regenerate.
* include/std/format (__literal_encoding_is_utf8): New function.
(_Seq_sink::view()): New member function.
* include/std/ostream (vprintf_nonunicode, vprintf_unicode)
(print, println): New functions.
* include/std/print: New file.
* src/c++23/Makefile.am: Add new source file.
* src/c++23/Makefile.in: Regenerate.
* src/c++23/print.cc: New file.
* testsuite/27_io/basic_ostream/print/1.cc: New test.
* testsuite/27_io/print/1.cc: New test.
* testsuite/27_io/print/2.cc: New test.
These tests are expected to run interactively, with the output checked
by eye. Nobody ever does that, but we can at least use dg-output to
check that the output is as expected.
libstdc++-v3/ChangeLog:
* testsuite/27_io/objects/char/2.cc: Use dg-output.
* testsuite/27_io/objects/wchar_t/2.cc: Use dg-output.
I forgot to 'git add' these files in the commit that added the new
member function to basic_filebuf.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_filebuf/native_handle/char/1.cc: New test.
* testsuite/27_io/basic_filebuf/native_handle/wchar_t/1.cc: New test.
The new __basic_file::native_handle() function can be added for C++11
and above, because the names "native_handle" and "native_handle_type"
are already reserved since C++11. Exporting those symbols from the
shared library does no harm, even if the feature gets dropped before the
C++23 standard is final.
The new member functions of std::fstream etc. are only declared for
C++26 and so are not instantiated in src/c++11/fstream-inst.cc. Declare
them with the always_inline attribute so that no symbol definitions are
needed in the library (we can change this later when C++26 support is
less experimental).
libstdc++-v3/ChangeLog:
* acinclude.m4 (GLIBCXX_CHECK_FILEBUF_NATIVE_HANDLES): New
macro.
* config.h.in: Regenerate.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.32): Export new
basic_filebuf members.
* config/io/basic_file_stdio.cc (__basic_file::native_handle):
Define new function.
* config/io/basic_file_stdio.h (__basic_file::native_handle):
Declare new function.
* configure: Regenerate.
* configure.ac: Use GLIBCXX_CHECK_FILEBUF_NATIVE_HANDLES.
* include/bits/version.def (fstream_native_handles): New macro.
* include/bits/version.h: Regenerate.
* include/std/fstream (basic_filebuf::native_handle)
(basic_fstream::native_handle, basic_ifstream::native_handle)
(basic_ofstream::native_handle): New functions.
* src/c++11/Makefile.am: Move compilation of basic_file.cc,
locale_init.cc and localename.cc to here.
* src/c++11/Makefile.in: Regenerate.
* src/c++98/locale_init.cc: Moved to...
* src/c++11/locale_init.cc: ...here.
* src/c++98/localename.cc: Moved to...
* src/c++11/localename.cc: ...here.
* src/c++98/Makefile.am: Remove basic_file.cc, locale_init.cc
and localename.cc from here.
* src/c++98/Makefile.in: Regenerate.
* testsuite/27_io/basic_filebuf/native_handle/version.cc: New test.
* testsuite/27_io/basic_fstream/native_handle/char/1.cc: New test.
* testsuite/27_io/basic_fstream/native_handle/wchar_t/1.cc: New test.
* testsuite/27_io/basic_ifstream/native_handle/char/1.cc: New test.
* testsuite/27_io/basic_ifstream/native_handle/wchar_t/1.cc: New test.
* testsuite/27_io/basic_ofstream/native_handle/char/1.cc: New test.
* testsuite/27_io/basic_ofstream/native_handle/wchar_t/1.cc: New test.
Some tests rely on text files with specific content being present in the
test directory. This has historically been done by copying
testsuite/data/*.tst and testsuite/data/*.txt to the test dir at the
start, in the libstdc++_init procedure. Some tests modify their data
files, so if the same test runs more than once in the same directory the
second and subsequent tests will see the modified files, and FAIL
because the content of the file is not in the expected state.
This change adds support for the dg-additional-files directive from the
main compiler testsuite and changes v3_target_compile to copy the
specified files to the directory where the test will run. This ensures
that a fresh copy of the files is present each time the test runs.
Eventually all tests could be transitioned to use dg-additional-files
and then libstdc++_init could be changed to remove the initial copy of
all files. This change only adds dg-additional-files to the tests that
modify their files and FAIL when re-run in the same directory.
The tests that rely on additional data files have comments containing
the strings "@require@" and "@diff@" which seem to be related to the
libstdc++-v3/mkcheck.in testing script that was removed in 2003. Those
comments can be used to find tests that should be migrated to use the
new dg-additional-files support, and then the comments can be removed.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_filebuf/seekoff/char/1-io.cc: Use
dg-additional-files. Remove @require@ and @diff@ comments.
* testsuite/27_io/basic_filebuf/seekoff/char/2-io.cc: Likewise.
* testsuite/27_io/basic_filebuf/seekpos/char/1-io.cc: Likewise.
* testsuite/27_io/basic_filebuf/seekpos/char/2-io.cc: Likewise.
* testsuite/lib/dg-options.exp (v3_additional_files): New
global variable.
(dg-additional-files): New proc.
* testsuite/lib/libstdc++.exp (v3_target_compile): Copy
additional files to test directory.
A target selector allows multiple target triplets, it's not necessary to
use the || operator in a logical expression.
libstdc++-v3/ChangeLog:
* testsuite/27_io/filesystem/path/concat/94063.cc: Simplify
dg-do target selector.
This test expects to be able to link, which fails if there are undefined
references to chdir, mkdir etc. in fs_ops.o in the libstdc++.a archive.
libstdc++-v3/ChangeLog:
* testsuite/27_io/filesystem/path/108636.cc: Add dg-require for
filesystem support.
The testcase added for this bug only checks conversion from wide strings
on construction, but the fix also covered conversion to wide stings via
path::wstring(). Add checks for that, and u16string() and u32string().
libstdc++-v3/ChangeLog:
PR libstdc++/95048
* testsuite/27_io/filesystem/path/construct/95048.cc: Check
conversions to wide strings.
* testsuite/experimental/filesystem/path/construct/95048.cc:
Likewise.
The <syncstream> header is only supported for the cxx11 ABI. The
declarations of basic_syncbuf, basic_osyncstream, syncbuf and
osyncstream were already correctly guarded by a check for
_GLIBCXX_USE_CXX11_ABI, but the wsyncbuf and wosyncstream declarations
were not.
libstdc++-v3/ChangeLog:
* testsuite/27_io/headers/iosfwd/synopsis.cc: Make wsyncbuf and
wosyncstream depend on _GLIBCXX_USE_CXX11_ABI.
The test wchar_t/94749.cc can take about 10 minutes on some
simulator/host combinations with char/94749.cc at a third of
that time. The cause is test05 which is quite heavy and
includes wrapping a 32-bit counter. Run it only for native
setups.
* testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc (main)
[! SIMULATOR_TEST]: Also exclude running test05.
* testsuite/27_io/basic_istream/ignore/char/94749.cc: Ditto.
libstdc++-v3/ChangeLog:
* testsuite/20_util/duration/cons/2.cc: Use values that aren't
affected by rounding.
* testsuite/20_util/from_chars/5.cc: Cast arithmetic result to
double before comparing for equality.
* testsuite/20_util/from_chars/6.cc: Likewise.
* testsuite/20_util/variant/86874.cc: Use values that aren't
affected by rounding.
* testsuite/25_algorithms/lower_bound/partitioned.cc: Compare to
original value instead of to floating-point-literal.
* testsuite/26_numerics/random/discrete_distribution/cons/range.cc:
Cast arithmetic result to double before comparing for equality.
* testsuite/26_numerics/random/piecewise_constant_distribution/cons/range.cc:
Likewise.
* testsuite/26_numerics/random/piecewise_linear_distribution/cons/range.cc:
Likewise.
* testsuite/26_numerics/valarray/transcend.cc (eq): Check that
the absolute difference is less than 0.01 instead of comparing
to two decimal places.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/01.cc:
Cast arithmetic result to double before comparing for equality.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/09.cc:
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/10.cc:
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/01.cc:
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/09.cc:
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/10.cc:
Likewise.
* testsuite/ext/random/hoyt_distribution/cons/parms.cc: Likewise.
The size reported by stat is always zero for some special files such as
those under /proc, which means the current copy_file implementation
thinks there is nothing to copy. Instead of trusting the stat value, try
to read a character from a streambuf and check for EOF.
libstdc++-v3/ChangeLog:
PR libstdc++/108178
* src/filesystem/ops-common.h (do_copy_file): Check for empty
files by trying to read a character.
* testsuite/27_io/filesystem/operations/copy_file_108178.cc:
New test.
Prior to N0966 (July 1996) the std::setfill manipulator was specified to
work with both input and output streams. In the final C++98 standard it
is only specified to work with output streams.
We have always supported it for input streams, despite that never being
in the standard, and having no meaning for any input streams defined by
the standard. This commit adds a deprecated attribute to the overload
for input streams, so that we can stop supporting this some day.
libstdc++-v3/ChangeLog:
PR libstdc++/109922
* include/std/iomanip (operator>>(basic_istream&, _Setfill)):
Add deprecated attribute to non-standard overload.
* doc/xml/manual/evolution.xml: Document deprecation.
* doc/html/*: Regenerate.
* testsuite/27_io/manipulators/standard/char/1.cc: Add
dg-warning for expected deprecated warning.
* testsuite/27_io/manipulators/standard/char/2.cc: Likewise.
* testsuite/27_io/manipulators/standard/wchar_t/1.cc: Likewise.
* testsuite/27_io/manipulators/standard/wchar_t/2.cc: Likewise.
vxworks ignores O_EXCL in open, so noreplace open succeeds when it is
expected to fail. xfail the tests.
for libstdc++-v3/ChangeLog
* testsuite/27_io/basic_ofstream/open/char/noreplace.cc: xfail
on vxworks.
* testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc:
Likewise.
Unlike the new str()&& members in <sstream>, there is no real difficulty
in supporting the new view() members for the old std::string ABI.
Enabling it fixes errors in <chrono> where std::ostringstream::view() is
used by ostream insertion operators for calendar types.
We just need to use [[gnu::always_inline]] on the view() members for the
old ABI, because the library doesn't contain instantiations of them for
the old ABI. Making them always inline avoids needing to add those
instantiations and export them.
libstdc++-v3/ChangeLog:
* include/std/sstream (basic_stringbuf::view): Define for old
std::string ABI.
(basic_istringstream::view, basic_0stringstream::view)
(basic_stringstream::view): Likewise.
* testsuite/27_io/basic_istringstream/view/char/1.cc: Remove
{ dg-require-effective-target cxx11_abi }.
* testsuite/27_io/basic_istringstream/view/wchar_t/1.cc:
Likewise.
* testsuite/27_io/basic_ostringstream/view/char/1.cc: Likewise.
* testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc:
Likewise.
* testsuite/27_io/basic_stringbuf/view/char/1.cc: Likewise.
* testsuite/27_io/basic_stringbuf/view/wchar_t/1.cc: Likewise.
* testsuite/27_io/basic_stringstream/view/char/1.cc: Likewise.
* testsuite/27_io/basic_stringstream/view/wchar_t/1.cc:
Likewise.
With -fkeep-inline-functions there are linker errors when including
<filesystem>. This happens because there are some filesystem::path
constructors defined inline which call non-exported functions defined in
the library. That's usually not a problem, because those constructors
are only called by code that's also inside the library. But when the
header is compiled with -fkeep-inline-functions those inline functions
are emitted even though they aren't called. That then creates an
undefined reference to the other library internsl. The fix is to just
move the private constructors into the library where they are called.
That way they are never even seen by users, and so not compiled even if
-fkeep-inline-functions is used.
On trunk there is a second problem, which is that the new equality
operators for comparing directory iterators with default_sentinel use
the shared_ptr::operator bool() conversion operator. The shared_ptr
specializations used by directory iterators are explicitly instantiated
in the library, but the bool conversion operators are not exported. This
causes linker errors at -O0 or with -fkeep-inline-functions. That just
requires the conversion operators to be exported.
libstdc++-v3/ChangeLog:
PR libstdc++/108636
* config/abi/pre/gnu.ver (GLIBCXX_3.4.31): Export shared_ptr
conversion operators for directory iterator comparisons with
std::default_sentinel_t.
* include/bits/fs_path.h (path::path(string_view, _Type))
(path::_Cmpt::_Cmpt(string_view, _Type, size_t)): Move inline
definitions to ...
* src/c++17/fs_path.cc: ... here.
* testsuite/27_io/filesystem/path/108636.cc: New test.
P0482R6 deprecated these functions for C++20. There was a ballot comment
on the C++23 CD saying to un-deprecate it, but LEWG just rejected that,
so let's add attributes to deprecate them.
libstdc++-v3/ChangeLog:
* include/bits/fs_path.h (u8path): Add deprecated attribute.
* testsuite/27_io/filesystem/path/construct/90281.cc: Add
-Wno-deprecated-declarations for C++20 and later.
* testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc:
Likewise.
* testsuite/27_io/filesystem/path/factory/u8path.cc: Likewise.
* testsuite/27_io/filesystem/path/native/string.cc: Likewise.
* testsuite/27_io/filesystem/path/factory/u8path-depr.cc: New test.
This copies the better tests from gcc-12 to trunk.
libstdc++-v3/ChangeLog:
PR libstdc++/106201
* testsuite/27_io/filesystem/iterators/106201.cc: Improve test.
* testsuite/experimental/filesystem/iterators/106201.cc: New test.
In commit r9-7381-g91756c4abc1757 I changed filesystem::path to use
std::codecvt<CharT, char, mbstate_t> for conversions from all wide
strings to UTF-8, instead of using std::codecvt_utf8<CharT>. This was
done because for 16-bit wchar_t, std::codecvt_utf8<wchar_t> only
supports UCS-2 and not UTF-16. The rationale for the change was sound,
but the actual fix was not. It's OK to use std::codecvt for char16_t or
char32_t, because the specializations for those types always use UTF-8 ,
but std::codecvt<wchar_t, char, mbstate_t> uses the current locale's
encodings, and the narrow encoding is probably ASCII and can't support
non-ASCII characters.
The correct fix is to use std::codecvt only for char16_t and char32_t.
For 32-bit wchar_t we could have continued using std::codecvt_utf8
because that uses UTF-32 which is fine, switching to std::codecvt broke
non-Windows targets with 32-bit wchar_t. For 16-bit wchar_t we did need
to change, but should have changed to std::codecvt_utf8_utf16<wchar_t>
instead, as that always uses UTF-16 not UCS-2. I actually noted that in
the commit message for r9-7381-g91756c4abc1757 but didn't use that
option. Oops.
This replaces the unconditional std::codecvt<CharT, char, mbstate_t>
with a type defined via template specialization, so it can vary
depending on the wide character type. The code is also simplified to
remove some of the mess of #ifdef and if-constexpr conditions.
libstdc++-v3/ChangeLog:
PR libstdc++/95048
* include/bits/fs_path.h (path::_Codecvt): New class template
that selects the kind of code conversion done.
(path::_Codecvt<wchar_t>): Select based on sizeof(wchar_t).
(_GLIBCXX_CONV_FROM_UTF8): New macro to allow the same code to
be used for Windows and POSIX.
(path::_S_convert(const EcharT*, const EcharT*)): Simplify by
using _Codecvt and _GLIBCXX_CONV_FROM_UTF8 abstractions.
(path::_S_str_convert(basic_string_view<value_type>, const A&)):
Simplify nested conditions.
* include/experimental/bits/fs_path.h (path::_Cvt): Define
nested typedef controlling type of code conversion done.
(path::_Cvt::_S_wconvert): Use new typedef.
(path::string(const A&)): Likewise.
* testsuite/27_io/filesystem/path/construct/95048.cc: New test.
* testsuite/experimental/filesystem/path/construct/95048.cc: New
test.
`basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
size 1024 and above, seemingly as an optimisation.
This can have a significant performance impact if the overhead of a
`write` syscall is non-negligible, e.g. on a slow disk, on network
filesystems, or simply during IO contention because instead of flushing
every `BUFSIZ` (by default), we can flush every 1024 char.
The impact is even greater with custom larger buffers, e.g. for network
filesystems, because the code could issue `write` for example 1000X more
often than necessary with respect to the buffer size.
It also introduces a significant discontinuity in performance when
writing chunks of size 1024 and above.
Instead, it makes sense to only bypass the buffer if the amount of data
to be written is larger than the buffer capacity.
Signed-off-by: Charles-Francois Natali <cf.natali@gmail.com>
libstdc++-v3/ChangeLog:
PR libstdc++/63746
* include/bits/fstream.tcc (basic_filbuf::xsputn): Remove
1024-byte chunking that bypasses the buffer for large writes.
* testsuite/27_io/basic_filebuf/sputn/char/63746.cc: New test.
In C++23 mode these tests started to FAIL because an rvalue reference
parameter can no longer be bound to an lvalue reference return type. As
confirmed by Ville (who added these tests) the problem overloads are not
intended to be called, and only exist to verify that they don't
interfere with the intended behaviour. This changes the function bodies
to just throw, so that the tests will fail if the function is called.
libstdc++-v3/ChangeLog:
* testsuite/27_io/basic_ostream/inserters_other/char/6.cc:
Change body of unused operator<< overload to throw if called.
* testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc:
Likewise.
This library defect was recently approved for C++23.
libstdc++-v3/ChangeLog:
* include/bits/fs_dir.h (directory_iterator): Add comparison
with std::default_sentinel_t. Remove redundant operator!= for
C++20.
* (recursive_directory_iterator): Likewise.
* include/bits/iterator_concepts.h [!__cpp_lib_concepts]
(default_sentinel_t, default_sentinel): Define even if concepts
are not supported.
* include/bits/regex.h (regex_iterator): Add comparison with
std::default_sentinel_t. Remove redundant operator!= for C++20.
(regex_token_iterator): Likewise.
(regex_token_iterator::_M_end_of_seq()): Add noexcept.
* testsuite/27_io/filesystem/iterators/lwg3719.cc: New test.
* testsuite/28_regex/iterators/regex_iterator/lwg3719.cc:
New test.
* testsuite/28_regex/iterators/regex_token_iterator/lwg3719.cc:
New test.
My P2467R1 proposal was accepted for C++23 so there's an official value
for this macro now.
libstdc++-v3/ChangeLog:
* include/bits/ios_base.h (__cpp_lib_ios_noreplace): Update
value to 202207L.
* include/std/version (__cpp_lib_ios_noreplace): Likewise.
* testsuite/27_io/basic_ofstream/open/char/noreplace.cc: Check
for new value.
* testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc:
Likewise.
In r11-2581-g17abcc77341584 (for LWG 2499) I added overflow checks to
the pre-C++20 operator>>(istream&, char*) overload. Those checks can
cause extraction to stop after filling the buffer, where previously it
would have tried to extract another character and stopped at EOF. When
that happens we no longer set eofbit in the stream state, which is
consistent with the behaviour of the new C++20 overload, but is an
observable and unexpected change in the C++17 behaviour. What makes it
worse is that the behaviour change is dependent on optimization, because
__builtin_object_size is used to detect the buffer size and that only
works when optimizing.
To avoid the unexpected and optimization-dependent change in behaviour,
set eofbit manually if we stopped extracting because of the buffer size
check, but had reached EOF anyway. If the stream's rdstate() != goodbit
or width() is non-zero and smaller than the buffer, there's nothing to
do. Otherwise, we filled the buffer and need to check for EOF, and maybe
set eofbit.
The new check is guarded by #ifdef __OPTIMIZE__ because otherwise
__builtin_object_size is useless. There's no point compiling and
emitting dead code that can't be eliminated because we're not
optimizing.
We could add extra checks that the next character in the buffer is not
whitespace, to detect the case where we stopped early and prevented a
buffer overflow that would have happened otherwise. That would allow us
to assert or set badbit in the stream state when undefined behaviour was
prevented. However, those extra checks would increase the size of the
function, potentially reducing the likelihood of it being inlined, and
so making the buffer size detection less reliable. It seems preferable
to prevent UB and silently truncate, rather than miss the UB and allow
the overflow to happen.
libstdc++-v3/ChangeLog:
PR libstdc++/106248
* include/std/istream [C++17] (operator>>(istream&, char*)):
Set eofbit if we stopped extracting at EOF.
* testsuite/27_io/basic_istream/extractors_character/char/pr106248.cc:
New test.
* testsuite/27_io/basic_istream/extractors_character/wchar_t/pr106248.cc:
New test.
Some of these are not truly "pure" because they access the file system,
e.g. exists and file_size, but they do not modify anything and are only
useful for the return value.
If you really want to use one of those functions just to check whether
an error is reported (either via an exception or an error_code&
argument) you can still do so, but you need to cast the discarded result
to void. Several tests need such a change, because they were indeed
only calling the functions to check for expected errors.
libstdc++-v3/ChangeLog:
* include/bits/fs_ops.h: Add nodiscard to all pure functions.
* include/experimental/bits/fs_ops.h: Likewise.
* testsuite/27_io/filesystem/operations/all.cc: Do not discard
results of absolute and canonical.
* testsuite/27_io/filesystem/operations/absolute.cc: Cast
discarded result to void.
* testsuite/27_io/filesystem/operations/canonical.cc: Likewise.
* testsuite/27_io/filesystem/operations/exists.cc: Likewise.
* testsuite/27_io/filesystem/operations/is_empty.cc: Likewise.
* testsuite/27_io/filesystem/operations/read_symlink.cc:
Likewise.
* testsuite/27_io/filesystem/operations/status.cc: Likewise.
* testsuite/27_io/filesystem/operations/symlink_status.cc:
Likewise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc:
Likewise.
* testsuite/experimental/filesystem/operations/canonical.cc:
Likewise.
* testsuite/experimental/filesystem/operations/exists.cc:
Likewise.
* testsuite/experimental/filesystem/operations/is_empty.cc:
Likewise.
* testsuite/experimental/filesystem/operations/read_symlink.cc:
Likewise.
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Likewise.
Currently the throwing overload of fs::temp_directory_path() will
discard the path that was obtained from the environment. When it fails
because the path doesn't resolve to a directory you get an unhelpful
error like:
filesystem error: temp_directory_path: Not a directory
It would be better to also print the path in that case, e.g.
filesystem error: temp_directory_path: Not a directory [/home/bob/tmp]
libstdc++-v3/ChangeLog:
* src/c++17/fs_ops.cc (fs::temp_directory_path()): Include path
in exception.
(fs::temp_directory_path(error_code&)): Rearrange to more
closely match the structure of the first overload.
* src/filesystem/ops.cc (fs::temp_directory_path): Likewise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc:
Check that exception contains the path.
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Likewise.
In the recent patch that introduced NO_SYMLINKS, I missed one of the
testcases that created symlinks.
for libstdc++-v3/ChangeLog
* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc
(test06): Don't create symlinks when NO_SYMLINKS is defined.
::rename on RTEMS does not meet several POSIX requirements, despite
compliance with C and C++ standards. ::std::filesystem::rename, in
turn, has requirements borrowed from POSIX, so it would have to be a
lot more than a simple wrapper around ::rename on RTEMS, and even then
fall short.
Until RTEMS reimplements ::rename for POSIX compliance, expect
filesystem rename tests to fail on it.
for libstdc++-v3/ChangeLog
* testsuite/27_io/filesystem/operations/rename.cc: xfail on
rtems.
* testsuite/experimental/filesystem/operations/rename.cc:
Likewise.
The last_write_time functions are defined in ways that are useful, or
that fail immediately, depending on various macros. When they fail
immediately, the filesystem last_write_time.cc tests fail noisily, but
the fail is entirely expected.
Define NO_LAST_WRITE_TIME in the last_write_time.cc tests, according
to the macros that select implementations of last_write_time, and use
it through the new dg-require-target-fs-lwt to skip tests that are
expected to fail.
for libstdc++-v3/ChangeLog
* testsuite/util/testsuite_fs.h (NO_LAST_WRITE_TIME): Define
when appropriate.
* testsuite/lib/libstdc++.exp
(check_v3_target_fs_last_write_time): New.
* testsuite/lib/dg-options.exp (dg-require-target-fs-lwt):
New.
* testsuite/27_io/filesystem/operations/last_write_time.cc:
Skip the test if the features are unavailable.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Likewise.
The do_space function is defined in ways that are useful, or that fail
immediately, depending on various macros. When it fails immediately,
the filesystem space.cc tests fail noisily, but the fail is entirely
expected.
Define NO_SPACE in testsuite_fs.h, according to the macros that select
implementations of do_space, and use it to skip tests that are
expected to fail, through a new dg-require.
for libstdc++-v3/ChangeLog
* testsuite/util/testsuite_fs.h (NO_SPACE): Define if
appropriate.
* testsuite/lib/libstdc++.exp (check_v3_target_fs_space): New.
* testsuite/lib/dg-options.exp (dg-require-target-fs-space):
New.
* testsuite/27_io/filesystem/operations/space.cc: Require
target-fs-space.
* testsuite/experimental/filesystem/operations/space.cc:
Likewise.