diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-06-02 19:35:37 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-06-02 19:35:37 +0100 |
commit | 4c19e432d63ec411dfab13294ac02af2ff11516c (patch) | |
tree | 22725a70454d80b6ac8bcfee93c8c8a34c4e29bb | |
parent | 0cbae4a7a23c0faf9c1e14ebd07e7b137b9b6792 (diff) | |
download | gcc-4c19e432d63ec411dfab13294ac02af2ff11516c.zip gcc-4c19e432d63ec411dfab13294ac02af2ff11516c.tar.gz gcc-4c19e432d63ec411dfab13294ac02af2ff11516c.tar.bz2 |
PR libstdc++/80624 satisfy invariant for char_traits<char16_t>::eof()
PR libstdc++/80624
* doc/xml/manual/status_cxx2011.xml: Document to_int_type behaviour.
* include/bits/char_traits.h (char_traits<char16_t>::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
6 files changed, 159 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1ad06f1..4d91484 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,13 @@ 2017-06-02 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/80624 + * doc/xml/manual/status_cxx2011.xml: Document to_int_type behaviour. + * include/bits/char_traits.h (char_traits<char16_t>::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 705f2ee..0fa4bc0 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. <classname>u32streampos</classname> are both synonyms for <classname>fpos<mbstate_t></classname>. The function <function>eof</function> returns <code>int_type(-1)</code>. + <function>char_traits<char16_t>::to_int_type</function> will + transform the "noncharacter" U+FFFF to U+FFFD (REPLACEMENT CHARACTER). + This is done to ensure that <function>to_int_type</function> never + returns the same value as <function>eof</function>, which is U+FFFF. </para> <para> diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 75db5b8..f19120b 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 0000000..05def7f --- /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 +// <http://www.gnu.org/licenses/>. + +// { dg-do compile { target c++11 } } + +#include <string> + + +constexpr bool not_equal_to_eof(char16_t c) +{ + using T = std::char_traits<char16_t>; + 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 0000000..c08c227 --- /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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { target c++11 } } + +#include <streambuf> +#include <testsuite_hooks.h> + +struct streambuf : std::basic_streambuf<char16_t> +{ + 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 0000000..a2a1917 --- /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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { target c++11 } } + +#include <streambuf> +#include <testsuite_hooks.h> + +struct streambuf : std::basic_streambuf<char16_t> +{ + 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(); +} |