https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86419

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Thanks, this is still present in the latest version of the code too.

This just includes the failing cases:

#include <cassert>
#include <locale>

using namespace std;

// 2 code points, both are 4 byte in UTF-8.
// in UTF-16 both are 2 unit i.e. surrogate pairs
const char* u8in = u8"\U0010FFFF\U0010AAAA";

//tests .in() function of codecvt<char16_t, char, mbstate>
auto test_u16_in()
{
        char16_t u16out[4];

        auto& cvt =
            use_facet<codecvt<char16_t, char, mbstate_t>>(locale::classic());
        auto state = mbstate_t{};
        auto in_ptr = u8in;
        auto out_ptr = u16out;

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        auto res =
            cvt.in(state, u8in, u8in + 6, in_ptr, u16out, u16out + 2, out_ptr);
        // actual output
        assert(res == cvt.partial); // BUG
        assert(out_ptr == u16out + 2);
        assert(in_ptr == u8in + 4);
        // expected output
        // assert(res == cvt.partial);
        // assert(out_ptr == u16str+2);
        // assert(in_ptr == u8str+4);

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        res =
            cvt.in(state, u8in, u8in + 8, in_ptr, u16out, u16out + 2, out_ptr);
        // actual output
        assert(res == cvt.partial); // BUG
        assert(out_ptr == u16out + 2);
        assert(in_ptr == u8in + 4);
        // expected output
        // assert(res == cvt.partial);
        // assert(out_ptr == u16str+2);
        // assert(in_ptr == u8str+4);
}

//tests .out() function of codecvt<char16_t, char, mbstate>
auto test_u16_out()
{
        const char16_t* u16in = u"\U0010FFFF\U0010AAAA";
        char u8out[8];

        auto& cvt =
            use_facet<codecvt<char16_t, char, mbstate_t>>(locale::classic());
        auto state = mbstate_t{};
        auto in_ptr = u16in;
        auto out_ptr = u8out;

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        auto res =
            cvt.out(state, u16in, u16in + 1, in_ptr, u8out, u8out + 3,
out_ptr);
        assert(res == cvt.partial); // BUG
        assert(in_ptr == u16in);
        assert(out_ptr == u8out);

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        res =
            cvt.out(state, u16in, u16in + 1, in_ptr, u8out, u8out + 4,
out_ptr);
        assert(res == cvt.partial); // BUG
        assert(in_ptr == u16in);
        assert(out_ptr == u8out);

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        res =
            cvt.out(state, u16in, u16in + 3, in_ptr, u8out, u8out + 4,
out_ptr);
        assert(res == cvt.partial); // BUG
        assert(in_ptr == u16in + 2);
        assert(out_ptr == u8out + 4);

        state = {};
        in_ptr = nullptr;
        out_ptr = nullptr;
        res =
            cvt.out(state, u16in, u16in + 3, in_ptr, u8out, u8out + 8,
out_ptr);
        assert(res == cvt.partial); // BUG
        assert(in_ptr == u16in + 2);
        assert(out_ptr == u8out + 4);
}

int main()
{
        test_u16_in();
        test_u16_out();
}

Reply via email to