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
This commit is contained in:
Jonathan Wakely 2017-06-02 19:35:37 +01:00 committed by Jonathan Wakely
parent 0cbae4a7a2
commit 4c19e432d6
6 changed files with 159 additions and 1 deletions

View file

@ -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.

View file

@ -2630,6 +2630,10 @@ particular release.
<classname>u32streampos</classname> are both synonyms for
<classname>fpos&lt;mbstate_t&gt;</classname>.
The function <function>eof</function> returns <code>int_type(-1)</code>.
<function>char_traits&lt;char16_t&gt;::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>

View file

@ -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

View file

@ -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");

View file

@ -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();
}

View file

@ -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();
}