From: Jonathan Wakely Date: Mon, 13 Jul 2015 20:07:48 +0000 (+0100) Subject: re PR libstdc++/66855 (codecvt wrong endianness in UTF-16 conversions) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=795038b72255040a9e62cc5da08bd6a6b5d11286;p=gcc.git re PR libstdc++/66855 (codecvt wrong endianness in UTF-16 conversions) PR libstdc++/66855 * src/c++11/codecvt.cc (__codecvt_utf8_utf16_base::do_in): Override endianness bit in mode. * testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc: New. From-SVN: r225748 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 93a9adb575f..59fbd1f6c39 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,10 @@ 2015-07-13 Jonathan Wakely + PR libstdc++/66855 + * src/c++11/codecvt.cc (__codecvt_utf8_utf16_base::do_in): Override + endianness bit in mode. + * testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc: New. + * include/bits/c++config (_GLIBCXX_NOEXCEPT_IF): Define. * include/bits/forward_list.h (forward_list::swap): Make noexcept unconditional. diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc index 6b82aa853e7..a454064ce60 100644 --- a/libstdc++-v3/src/c++11/codecvt.cc +++ b/libstdc++-v3/src/c++11/codecvt.cc @@ -1264,7 +1264,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, { range from{ __from, __from_end }; range to{ __to, __to_end }; - auto res = utf16_in(from, to, _M_maxcode, _M_mode); + codecvt_mode mode = codecvt_mode(_M_mode | (consume_header|generate_header)); +#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ + mode = codecvt_mode(mode | little_endian); +#endif + auto res = utf16_in(from, to, _M_maxcode, mode); __from_next = from.next; __to_next = to.next; return res; diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc new file mode 100644 index 00000000000..3f99cb416f4 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/66855.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2015 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-options "-std=gnu++11" } + +#include +#include + +void +test01() +{ + std::codecvt_utf8_utf16 cvt; + char16_t utf16[] = u"\ub098\ub294\ud0dc\uc624"; + const char16_t* nf16; + char utf8[16]; + char* nt8; + std::mbstate_t st{}; + auto res = cvt.out(st, utf16, utf16+4, nf16, utf8, utf8+16, nt8); + VERIFY( res == std::codecvt_base::ok ); + + st = {}; + char16_t buf[4] = {}; + const char* nf8 = nt8; + char16_t* nt16; + res = cvt.in(st, utf8, nf8, nf8, buf, buf+4, nt16); + VERIFY( res == std::codecvt_base::ok ); + VERIFY( nt16 == buf+4 ); + VERIFY( buf[0] == utf16[0] ); + VERIFY( buf[1] == utf16[1] ); + VERIFY( buf[2] == utf16[2] ); + VERIFY( buf[3] == utf16[3] ); +} + +int +main() +{ + test01(); +}