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

Reply via email to