http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60397
Bug ID: 60397 Summary: The value of char16_t u'\uffff' is 0xdfff instead of 0xffff Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: wjl at icecavern dot net CC: daniel.kruegler at googlemail dot com Created attachment 32247 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32247&action=edit uffff.c++ -- program that shows the problem +++ This bug was initially created as a clone of Bug #59873 +++ I found another major bug with char16_t literals when trying to encode a U+FFFF. 1) A incorrect warning is emitted. 2) The value is incorrectly changed from U+FFFF to U+DFFF (a low surrogate). This is very similar to, but different that, bug #59873. Because this problem seems related, I've shown both the U+FFFF and U+0000 problem in the provided example code that triggers the bug. Notice that they fail in similar, but different, ways. (For reference to those who care about other compilers, none of these problems appear using clang 3.5.) The following demonstrates the problem with both g++ 4.8.2 (released) and g++ 4.9.0 (trunk): # First with g++ 4.8.2 $ g++ --version g++ (Debian 4.8.2-14) 4.8.2 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ -std=c++11 uffff.c++ uffff.c++:3:16: warning: character constant too long for its type [enabled by default] static_assert(u'\uffff' == 0xffff, "FAILS"); ^ uffff.c++:7:16: warning: character constant too long for its type [enabled by default] static_assert(u'\U0000ffff' == 0xffff, "FAILS"); ^ uffff.c++:19:16: warning: character constant too long for its type [enabled by default] static_assert(u'\uffff' != 0xdfff, "FAILS"); ^ uffff.c++:21:16: warning: character constant too long for its type [enabled by default] static_assert(u'\U0000ffff' != 0xdfff, "FAILS"); ^ uffff.c++: In function ‘int main()’: uffff.c++:3:2: error: static assertion failed: FAILS static_assert(u'\uffff' == 0xffff, "FAILS"); ^ uffff.c++:7:2: error: static assertion failed: FAILS static_assert(u'\U0000ffff' == 0xffff, "FAILS"); ^ uffff.c++:11:2: error: static assertion failed: FAILS static_assert(u"\uffff"[0] == 0xffff, "FAILS"); ^ uffff.c++:15:2: error: static assertion failed: FAILS static_assert(u"\U0000ffff"[0] == 0xffff, "FAILS"); ^ uffff.c++:19:2: error: static assertion failed: FAILS static_assert(u'\uffff' != 0xdfff, "FAILS"); ^ uffff.c++:21:2: error: static assertion failed: FAILS static_assert(u'\U0000ffff' != 0xdfff, "FAILS"); ^ uffff.c++:28:2: error: static assertion failed: FAILS static_assert(u'\u0000' == 0x0000, "FAILS"); ^ uffff.c++:30:2: error: static assertion failed: FAILS static_assert(U'\u0000' == 0x0000, "FAILS"); ^ uffff.c++:32:2: error: static assertion failed: FAILS static_assert(u'\U00000000' == 0x0000, "FAILS"); ^ uffff.c++:34:2: error: static assertion failed: FAILS static_assert(U'\U00000000' == 0x0000, "FAILS"); ^ uffff.c++:36:2: error: static assertion failed: FAILS static_assert(u"\u0000"[0] == 0x0000, "FAILS"); ^ uffff.c++:38:2: error: static assertion failed: FAILS static_assert(U"\u0000"[0] == 0x0000, "FAILS"); ^ uffff.c++:40:2: error: static assertion failed: FAILS static_assert(u"\U00000000"[0] == 0x0000, "FAILS"); ^ uffff.c++:42:2: error: static assertion failed: FAILS static_assert(U"\U00000000"[0] == 0x0000, "FAILS"); ^ uffff.c++:45:2: error: static assertion failed: FAILS static_assert(u'\u0000' != 0x0001, "FAILS"); ^ uffff.c++:46:2: error: static assertion failed: FAILS static_assert(U'\u0000' != 0x0001, "FAILS"); ^ uffff.c++:47:2: error: static assertion failed: FAILS static_assert(u'\U00000000' != 0x0001, "FAILS"); ^ uffff.c++:48:2: error: static assertion failed: FAILS static_assert(U'\U00000000' != 0x0001, "FAILS"); ^ uffff.c++:49:2: error: static assertion failed: FAILS static_assert(u"\u0000"[0] != 0x0001, "FAILS"); ^ uffff.c++:50:2: error: static assertion failed: FAILS static_assert(U"\u0000"[0] != 0x0001, "FAILS"); ^ uffff.c++:51:2: error: static assertion failed: FAILS static_assert(u"\U00000000"[0] != 0x0001, "FAILS"); ^ uffff.c++:52:2: error: static assertion failed: FAILS static_assert(U"\U00000000"[0] != 0x0001, "FAILS"); ^ # Change to g++ 4.9.0 $ g++ --version g++ (Debian 4.9-20140218-1) 4.9.0 20140218 (experimental) [trunk revision 207856] Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ -std=c++11 uffff.c++ 2>&1 uffff.c++:3:16: warning: character constant too long for its type static_assert(u'\uffff' == 0xffff, "FAILS"); ^ uffff.c++:7:16: warning: character constant too long for its type static_assert(u'\U0000ffff' == 0xffff, "FAILS"); ^ uffff.c++:19:16: warning: character constant too long for its type static_assert(u'\uffff' != 0xdfff, "FAILS"); ^ uffff.c++:21:16: warning: character constant too long for its type static_assert(u'\U0000ffff' != 0xdfff, "FAILS"); ^ uffff.c++: In function ‘int main()’: uffff.c++:3:2: error: static assertion failed: FAILS static_assert(u'\uffff' == 0xffff, "FAILS"); ^ uffff.c++:7:2: error: static assertion failed: FAILS static_assert(u'\U0000ffff' == 0xffff, "FAILS"); ^ uffff.c++:11:2: error: static assertion failed: FAILS static_assert(u"\uffff"[0] == 0xffff, "FAILS"); ^ uffff.c++:15:2: error: static assertion failed: FAILS static_assert(u"\U0000ffff"[0] == 0xffff, "FAILS"); ^ uffff.c++:19:2: error: static assertion failed: FAILS static_assert(u'\uffff' != 0xdfff, "FAILS"); ^ uffff.c++:21:2: error: static assertion failed: FAILS static_assert(u'\U0000ffff' != 0xdfff, "FAILS"); ^ uffff.c++:28:2: error: static assertion failed: FAILS static_assert(u'\u0000' == 0x0000, "FAILS"); ^ uffff.c++:30:2: error: static assertion failed: FAILS static_assert(U'\u0000' == 0x0000, "FAILS"); ^ uffff.c++:32:2: error: static assertion failed: FAILS static_assert(u'\U00000000' == 0x0000, "FAILS"); ^ uffff.c++:34:2: error: static assertion failed: FAILS static_assert(U'\U00000000' == 0x0000, "FAILS"); ^ uffff.c++:36:2: error: static assertion failed: FAILS static_assert(u"\u0000"[0] == 0x0000, "FAILS"); ^ uffff.c++:38:2: error: static assertion failed: FAILS static_assert(U"\u0000"[0] == 0x0000, "FAILS"); ^ uffff.c++:40:2: error: static assertion failed: FAILS static_assert(u"\U00000000"[0] == 0x0000, "FAILS"); ^ uffff.c++:42:2: error: static assertion failed: FAILS static_assert(U"\U00000000"[0] == 0x0000, "FAILS"); ^ uffff.c++:45:2: error: static assertion failed: FAILS static_assert(u'\u0000' != 0x0001, "FAILS"); ^ uffff.c++:46:2: error: static assertion failed: FAILS static_assert(U'\u0000' != 0x0001, "FAILS"); ^ uffff.c++:47:2: error: static assertion failed: FAILS static_assert(u'\U00000000' != 0x0001, "FAILS"); ^ uffff.c++:48:2: error: static assertion failed: FAILS static_assert(U'\U00000000' != 0x0001, "FAILS"); ^ uffff.c++:49:2: error: static assertion failed: FAILS static_assert(u"\u0000"[0] != 0x0001, "FAILS"); ^ uffff.c++:50:2: error: static assertion failed: FAILS static_assert(U"\u0000"[0] != 0x0001, "FAILS"); ^ uffff.c++:51:2: error: static assertion failed: FAILS static_assert(u"\U00000000"[0] != 0x0001, "FAILS"); ^ uffff.c++:52:2: error: static assertion failed: FAILS static_assert(U"\U00000000"[0] != 0x0001, "FAILS"); ^