From: Jonathan Wakely Date: Fri, 2 Jun 2017 18:35:37 +0000 (+0100) Subject: PR libstdc++/80624 satisfy invariant for char_traits::eof() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4c19e432d63ec411dfab13294ac02af2ff11516c;p=gcc.git PR libstdc++/80624 satisfy invariant for char_traits::eof() PR libstdc++/80624 * doc/xml/manual/status_cxx2011.xml: Document to_int_type behaviour. * include/bits/char_traits.h (char_traits::to_int_type): Transform eof value to U+FFFD. * testsuite/21_strings/char_traits/requirements/char16_t/eof.cc: New. * testsuite/27_io/basic_streambuf/sgetc/char16_t/80624.cc: New. * testsuite/27_io/basic_streambuf/sputc/char16_t/80624.cc: New. From-SVN: r248843 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1ad06f1f4d1..4d9148437d5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,13 @@ 2017-06-02 Jonathan Wakely + PR libstdc++/80624 + * doc/xml/manual/status_cxx2011.xml: Document to_int_type behaviour. + * include/bits/char_traits.h (char_traits::to_int_type): + Transform eof value to U+FFFD. + * testsuite/21_strings/char_traits/requirements/char16_t/eof.cc: New. + * testsuite/27_io/basic_streambuf/sgetc/char16_t/80624.cc: New. + * testsuite/27_io/basic_streambuf/sputc/char16_t/80624.cc: New. + * libsupc++/Makefile.am: Remove custom targets for files that need to be compiled as C++11 or C++14. * libsupc++/Makefile.in: Regenerate. diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index 705f2eecc60..0fa4bc0dffe 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -2630,6 +2630,10 @@ particular release. u32streampos are both synonyms for fpos<mbstate_t>. The function eof returns int_type(-1). + char_traits<char16_t>::to_int_type will + transform the "noncharacter" U+FFFF to U+FFFD (REPLACEMENT CHARACTER). + This is done to ensure that to_int_type never + returns the same value as eof, which is U+FFFF. diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 75db5b89321..f19120bd16a 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -507,7 +507,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr int_type to_int_type(const char_type& __c) noexcept - { return int_type(__c); } + { return __c == eof() ? int_type(0xfffd) : int_type(__c); } static constexpr bool eq_int_type(const int_type& __c1, const int_type& __c2) noexcept diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char16_t/eof.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char16_t/eof.cc new file mode 100644 index 00000000000..05def7f67d4 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char16_t/eof.cc @@ -0,0 +1,31 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + + +constexpr bool not_equal_to_eof(char16_t c) +{ + using T = std::char_traits; + return T::eq_int_type(T::eof(), T::to_int_type(c)) == false; +} + +// Last two code points of the BMP are noncharacters: +static_assert(not_equal_to_eof(u'\uFFFE'), "U+FFFE compares unequal to eof"); +static_assert(not_equal_to_eof(u'\uFFFF'), "U+FFFF compares unequal to eof"); diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/sgetc/char16_t/80624.cc b/libstdc++-v3/testsuite/27_io/basic_streambuf/sgetc/char16_t/80624.cc new file mode 100644 index 00000000000..c08c2274706 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_streambuf/sgetc/char16_t/80624.cc @@ -0,0 +1,56 @@ +// 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +struct streambuf : std::basic_streambuf +{ + basic_streambuf* setbuf(char_type* s, std::streamsize n) override + { + setp(s, s + n); + setg(s, s, s + n); + return this; + } +}; + +void +test01() +{ + using traits = streambuf::traits_type; + + char16_t buf[2] = { streambuf::char_type(-1), streambuf::char_type(-2) }; + streambuf sb; + sb.pubsetbuf(buf, 2); + + streambuf::int_type res; + + res = sb.sbumpc(); + VERIFY( traits::eq_int_type(res, traits::eof()) == false ); + res = sb.sbumpc(); + VERIFY( traits::eq_int_type(res, traits::eof()) == false ); + res = sb.sbumpc(); + VERIFY( traits::eq_int_type(res, traits::eof()) == true ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/sputc/char16_t/80624.cc b/libstdc++-v3/testsuite/27_io/basic_streambuf/sputc/char16_t/80624.cc new file mode 100644 index 00000000000..a2a19176514 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_streambuf/sputc/char16_t/80624.cc @@ -0,0 +1,59 @@ +// 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +struct streambuf : std::basic_streambuf +{ + basic_streambuf* setbuf(char_type* s, std::streamsize n) override + { + setp(s, s + n); + setg(s, s, s + n); + return this; + } +}; + +void +test01() +{ + using traits = streambuf::traits_type; + + char16_t buf[2] = { }; + streambuf sb; + sb.pubsetbuf(buf, 2); + + streambuf::int_type res; + + res = sb.sputc(streambuf::char_type(-1)); + VERIFY( traits::eq_int_type(res, traits::eof()) == false ); + res = sb.sputc(streambuf::char_type(-2)); + VERIFY( traits::eq_int_type(res, traits::eof()) == false ); + res = sb.sputc(streambuf::char_type(1)); + VERIFY( traits::eq_int_type(res, traits::eof()) == true ); + + VERIFY( buf[0] == streambuf::char_type(-1) ); + VERIFY( buf[1] == streambuf::char_type(-2) ); +} + +int +main() +{ + test01(); +}