From c466b2cd136139e0e9fef6019fa6f136e23c7a4c Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 18 Jul 2008 20:23:42 +0000 Subject: [PATCH] c-common.c (c_stddef_cpp_builtins): Define __CHAR16_TYPE__ and __CHAR32_TYPE__. gcc/ChangeLog: 2008-07-16 Kris Van Hees * c-common.c (c_stddef_cpp_builtins): Define __CHAR16_TYPE__ and __CHAR32_TYPE__. * c-typeck.c (digest_init): Support char16_t and char32_t. (set_nonincremental_init_from_string): Idem. gcc/cp/ChangeLog: 2008-07-16 Kris Van Hees * rtti.c (emit_support_tinfos): Add char16_type_node and char32_type_node. * typeck2.c (digest_init): Support char16_t and char32_t. gcc/testsuite/ChangeLog: 2008-07-16 Kris Van Hees Tests for char16_t and char32_t support. * g++.dg/ext/utf-array.C: New * g++.dg/ext/utf-array-short-wchar.C: New * g++.dg/ext/utf-rtti.C: New * g++.dg/ext/utf-type.c: New * gcc.dg/utf-array.c: New * gcc.dg/utf-array-short-wchar.c: New * gcc.dg/utf-inc-init.c: New * gcc.dg/utf-type.c: New libstdc++-v3/ChangeLog: 2008-07-16 Kris Van Hees Holger Hopp * config/abi/pre/gnu.ver: Support char16_t and char32_t. * testsuite/util/testsuite_abi.cc (check_version): Add CXXABI_1.3.3 to known_versions. From-SVN: r137965 --- gcc/ChangeLog | 7 ++ gcc/c-common.c | 2 + gcc/c-typeck.c | 55 +++++++------ gcc/cp/ChangeLog | 26 +++--- gcc/cp/rtti.c | 2 +- gcc/cp/typeck2.c | 25 ++++-- gcc/testsuite/ChangeLog | 12 +++ .../g++.dg/ext/utf-array-short-wchar.C | 72 ++++++++++++++++ gcc/testsuite/g++.dg/ext/utf-array.C | 72 ++++++++++++++++ gcc/testsuite/g++.dg/ext/utf-rtti.C | 12 +++ gcc/testsuite/g++.dg/ext/utf-type.C | 15 ++++ gcc/testsuite/gcc.dg/utf-array-short-wchar.c | 82 +++++++++++++++++++ gcc/testsuite/gcc.dg/utf-array.c | 82 +++++++++++++++++++ gcc/testsuite/gcc.dg/utf-inc-init.c | 45 ++++++++++ gcc/testsuite/gcc.dg/utf-type.c | 18 ++++ libstdc++-v3/ChangeLog | 8 ++ libstdc++-v3/config/abi/pre/gnu.ver | 12 +++ libstdc++-v3/testsuite/util/testsuite_abi.cc | 1 + 18 files changed, 502 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C create mode 100644 gcc/testsuite/g++.dg/ext/utf-array.C create mode 100644 gcc/testsuite/g++.dg/ext/utf-rtti.C create mode 100644 gcc/testsuite/g++.dg/ext/utf-type.C create mode 100644 gcc/testsuite/gcc.dg/utf-array-short-wchar.c create mode 100644 gcc/testsuite/gcc.dg/utf-array.c create mode 100644 gcc/testsuite/gcc.dg/utf-inc-init.c create mode 100644 gcc/testsuite/gcc.dg/utf-type.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c535ef5c4f..e074ef6c6cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-07-18 Kris Van Hees + + * c-common.c (c_stddef_cpp_builtins): Define __CHAR16_TYPE__ + and __CHAR32_TYPE__. + * c-typeck.c (digest_init): Support char16_t and char32_t. + (set_nonincremental_init_from_string): Idem. + 2008-07-18 H.J. Lu PR middle-end/36859 diff --git a/gcc/c-common.c b/gcc/c-common.c index e93d2fba6df..cc13e056fd5 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4895,6 +4895,8 @@ c_stddef_cpp_builtins(void) builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0); builtin_define_with_value ("__INTMAX_TYPE__", INTMAX_TYPE, 0); builtin_define_with_value ("__UINTMAX_TYPE__", UINTMAX_TYPE, 0); + builtin_define_with_value ("__CHAR16_TYPE__", CHAR16_TYPE, 0); + builtin_define_with_value ("__CHAR32_TYPE__", CHAR32_TYPE, 0); } static void diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6b7594e6a26..dafce2ac23c 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4704,47 +4704,56 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) || typ1 == signed_char_type_node || typ1 == unsigned_char_type_node); bool wchar_array = !!comptypes (typ1, wchar_type_node); - if (char_array || wchar_array) + bool char16_array = !!comptypes (typ1, char16_type_node); + bool char32_array = !!comptypes (typ1, char32_type_node); + + if (char_array || wchar_array || char16_array || char32_array) { struct c_expr expr; - bool char_string; + tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))); expr.value = inside_init; expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); maybe_warn_string_init (type, expr); - char_string - = (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) - == char_type_node); - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), TYPE_MAIN_VARIANT (type))) return inside_init; - if (!wchar_array && !char_string) + if (char_array) { - error_init ("char-array initialized from wide string"); - return error_mark_node; + if (typ2 != char_type_node) + { + error_init ("char-array initialized from wide string"); + return error_mark_node; + } } - if (char_string && !char_array) + else { - error_init ("wchar_t-array initialized from non-wide string"); - return error_mark_node; + if (typ2 == char_type_node) + { + error_init ("wide character array initialized from non-wide " + "string"); + return error_mark_node; + } + else if (!comptypes(typ1, typ2)) + { + error_init ("wide character array initialized from " + "incompatible wide string"); + return error_mark_node; + } } TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != 0 && TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - /* Subtract 1 (or sizeof (wchar_t)) + /* Subtract the size of a single (possibly wide) character because it's ok to ignore the terminating null char that is counted in the length of the constant. */ && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), TREE_STRING_LENGTH (inside_init) - - ((TYPE_PRECISION (typ1) - != TYPE_PRECISION (char_type_node)) - ? (TYPE_PRECISION (wchar_type_node) - / BITS_PER_UNIT) - : 1))) + - (TYPE_PRECISION (typ1) + / BITS_PER_UNIT))) pedwarn_init ("initializer-string for array of chars is too long"); return inside_init; @@ -6092,15 +6101,7 @@ set_nonincremental_init_from_string (tree str) gcc_assert (TREE_CODE (constructor_type) == ARRAY_TYPE); - if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) - == TYPE_PRECISION (char_type_node)) - wchar_bytes = 1; - else - { - gcc_assert (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) - == TYPE_PRECISION (wchar_type_node)); - wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; - } + wchar_bytes = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) / BITS_PER_UNIT; charwidth = TYPE_PRECISION (char_type_node); type = TREE_TYPE (constructor_type); p = TREE_STRING_POINTER (str); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d67a10b0283..6daff1e9df5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,4 +1,10 @@ -2008-07-18 Kaveh R. Ghazi +2008-07-18 Kris Van Hees + + * rtti.c (emit_support_tinfos): Add char16_type_node and + char32_type_node. + * typeck2.c (digest_init): Support char16_t and char32_t. + +2008-07-18 Kavih R. Ghazi * cvt.c (convert_to_void): Avoid C++ keywords. * decl.c (walk_namespaces_r, wrapup_globals_for_namespace): @@ -59,9 +65,9 @@ 2008-07-11 Dodji Seketeli PR c++/31754 - * cp-tree.h (struct cp_decl_specifier_seq): add a location field. It + * cp-tree.h (struct cp_decl_specifier_seq): Add a location field. It carries the location of the primary type. - * parser.c (cp_parser_check_type_definition): update documentation. + * parser.c (cp_parser_check_type_definition): Update documentation. (cp_parser_check_for_definition_in_return_type, cp_parser_check_for_invalid_template_id, cp_parser_set_decl_spec_type, @@ -69,18 +75,18 @@ cp_parser_diagnose_invalid_type_name, cp_parser_new_expression, cp_parser_explicit_instantiation, cp_parser_type_specifier, cp_parser_simple_type_specifier, - cp_parser_omp_for_loop, cp_parser_pragma): use location in error messages. - + cp_parser_omp_for_loop, cp_parser_pragma): Use location in error + messages. 2008-07-11 Dodji Seketeli PR c++/31754 * pt.c, semantic.c: * semantic.c (qualified_name_lookup_error, finish_id_expression): - add a location_t parameter so that + Add a location_t parameter so that error message can have a more accurate location. - * cp-tree.h: updated prototype - * pt.c (tsubst_qualified_id): use location in error messages. + * cp-tree.h: Updated prototype + * pt.c (tsubst_qualified_id): Use location in error messages. * parser.c (cp_parser_postfix_expression, cp_parser_objc_statement, cp_parser_trait_expr, cp_parser_token_is_class_key, @@ -103,8 +109,8 @@ cp_parser_function_specifier_opt, cp_parser_decltype, cp_parser_mem_initializer_list, cp_parser_mem_initializer, cp_parser_mem_initializer_id, cp_parser_template_parameter, - cp_parser_type_parameter, cp_parser_template_id, cp_parser_template_name, - cp_parser_template_argument): likewise. + cp_parser_type_parameter, cp_parser_template_id, + cp_parser_template_name, cp_parser_template_argument): Likewise. 2008-07-09 Paolo Carlini diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 8a36f0b77b7..d2e544b0f9e 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1408,7 +1408,7 @@ emit_support_tinfos (void) { &void_type_node, &boolean_type_node, - &wchar_type_node, + &wchar_type_node, &char16_type_node, &char32_type_node, &char_type_node, &signed_char_type_node, &unsigned_char_type_node, &short_integer_type_node, &short_unsigned_type_node, &integer_type_node, &unsigned_type_node, diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 4cf8021964f..a30ff547f18 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -727,17 +727,26 @@ digest_init_r (tree type, tree init, bool nested) { tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init))); - if (char_type != char_type_node - && TYPE_PRECISION (typ1) == BITS_PER_UNIT) + if (TYPE_PRECISION (typ1) == BITS_PER_UNIT) { - error ("char-array initialized from wide string"); - return error_mark_node; + if (char_type != char_type_node) + { + error ("char-array initialized from wide string"); + return error_mark_node; + } } - if (char_type == char_type_node - && TYPE_PRECISION (typ1) != BITS_PER_UNIT) + else { - error ("int-array initialized from non-wide string"); - return error_mark_node; + if (char_type == char_type_node) + { + error ("int-array initialized from non-wide string"); + return error_mark_node; + } + else if (char_type != typ1) + { + error ("int-array initialized from incompatible wide string"); + return error_mark_node; + } } TREE_TYPE (init) = type; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cdf587a21ee..79793fd3999 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2008-07-18 Kris Van Hees + + Tests for char16_t and char32_t support. + * g++.dg/ext/utf-array.C: New + * g++.dg/ext/utf-array-short-wchar.C: New + * g++.dg/ext/utf-rtti.C: New + * g++.dg/ext/utf-type.c: New + * gcc.dg/utf-array.c: New + * gcc.dg/utf-array-short-wchar.c: New + * gcc.dg/utf-inc-init.c: New + * gcc.dg/utf-type.c: New + 2008-07-18 H.J. Lu PR middle-end/36859 diff --git a/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C new file mode 100644 index 00000000000..7d768d307a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C @@ -0,0 +1,72 @@ +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x -fshort-wchar" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x -fshort-wchar" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s32_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_7[3] = u"ab"; +const char16_t s32_8[4] = u"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/g++.dg/ext/utf-array.C b/gcc/testsuite/g++.dg/ext/utf-array.C new file mode 100644 index 00000000000..ff6e12df46d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-array.C @@ -0,0 +1,72 @@ +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s32_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_6[2] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_7[3] = u"ab"; +const char16_t s32_8[4] = u"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/g++.dg/ext/utf-rtti.C b/gcc/testsuite/g++.dg/ext/utf-rtti.C new file mode 100644 index 00000000000..b5d201b4d7a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-rtti.C @@ -0,0 +1,12 @@ +/* Contributed by Kris Van Hees */ +/* Ensure that typeinfo data is generated for char16_t/char32_t. */ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ + +#include + +int main(void) +{ + typeid(char16_t).name(); + typeid(char32_t).name(); +} diff --git a/gcc/testsuite/g++.dg/ext/utf-type.C b/gcc/testsuite/g++.dg/ext/utf-type.C new file mode 100644 index 00000000000..41a83ff2ef0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-type.C @@ -0,0 +1,15 @@ +/* Contributed by Kris Van Hees */ +/* Ensure that __CHAR16_TYPE__ and __CHAR32_TYPE__ exist, match the types they + are the underlying data type for. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +int main () +{ + if (sizeof (__CHAR16_TYPE__) != sizeof (char16_t)) + abort(); + if (sizeof (__CHAR32_TYPE__) != sizeof (char32_t)) + abort(); +} diff --git a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c new file mode 100644 index 00000000000..3f34caa19e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c @@ -0,0 +1,82 @@ +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fshort-wchar" } */ + +#include + +typedef short unsigned int char16_t; +typedef unsigned int char32_t; + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fshort-wchar" } */ + +#include + +typedef short unsigned int char16_t; +typedef unsigned int char32_t; + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s32_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_6[2] = u"ab"; +const char16_t s32_7[3] = u"ab"; +const char16_t s32_8[4] = u"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/gcc.dg/utf-array.c b/gcc/testsuite/gcc.dg/utf-array.c new file mode 100644 index 00000000000..0e36e0db607 --- /dev/null +++ b/gcc/testsuite/gcc.dg/utf-array.c @@ -0,0 +1,82 @@ +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +#include + +typedef short unsigned int char16_t; +typedef unsigned int char32_t; + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; +/* Contributed by Kris Van Hees */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +#include + +typedef short unsigned int char16_t; +typedef unsigned int char32_t; + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s32_4[0] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_5[1] = u"ab"; /* { dg-warning "chars is too long" } */ +const char16_t s32_6[2] = u"ab"; +const char16_t s32_7[3] = u"ab"; +const char16_t s32_8[4] = u"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/gcc.dg/utf-inc-init.c b/gcc/testsuite/gcc.dg/utf-inc-init.c new file mode 100644 index 00000000000..17d59f3782f --- /dev/null +++ b/gcc/testsuite/gcc.dg/utf-inc-init.c @@ -0,0 +1,45 @@ +/* Contributed by Kris Van Hees */ +/* Test incremental initializers for char16_t/char32_t arrays. */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +typedef __SIZE_TYPE__ size_t; +typedef short unsigned int char16_t; +typedef unsigned int char32_t; + +extern int memcmp (const void *, const void *, size_t); +extern void abort (void); +extern void exit (int); + +struct A { + char16_t S[6]; + int M; +} a[] = { { { u"foo" }, 1 }, [0].S[2] = u'x', [0].S[4] = u'y' }; +struct A b[] = { { { u"foo" }, 1 }, [0] = { .S[0] = u'b' } }; +struct A c[] = { { { u"foo" }, 1 }, [0].S = { u"a" }, [0].M = 2 }; + +struct B { + char32_t S[6]; + int M; +} d[] = { { { U"foo" }, 1 }, [0].S[2] = U'x', [0].S[4] = U'y' }; +struct B e[] = { { { U"foo" }, 1 }, [0] = { .S[0] = U'b' } }; +struct B f[] = { { { U"foo" }, 1 }, [0].S = { U"a" }, [0].M = 2 }; + +int main (void) +{ + if (memcmp (a[0].S, u"fox\0y", 6 * sizeof(char16_t)) || a[0].M != 1) + abort (); + if (memcmp (b[0].S, u"b\0\0\0\0", 6) || b[0].M) + abort (); + if (memcmp (c[0].S, u"a\0\0\0\0", 6) || c[0].M != 2) + abort (); + + if (memcmp (d[0].S, U"fox\0y", 6 * sizeof(char32_t)) || d[0].M != 1) + abort (); + if (memcmp (e[0].S, U"b\0\0\0\0", 6) || e[0].M) + abort (); + if (memcmp (f[0].S, U"a\0\0\0\0", 6) || f[0].M != 2) + abort (); + + exit(0); +} diff --git a/gcc/testsuite/gcc.dg/utf-type.c b/gcc/testsuite/gcc.dg/utf-type.c new file mode 100644 index 00000000000..1aa6020cbef --- /dev/null +++ b/gcc/testsuite/gcc.dg/utf-type.c @@ -0,0 +1,18 @@ +/* Contributed by Kris Van Hees */ +/* Ensure that __CHAR16_TYPE__ and __CHAR32_TYPE__ exist, and are of the + correct width. */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99 -Wall -Werror" } */ + +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; + +extern void abort (void); + +int main () +{ + if (sizeof (char16_t) != sizeof (u'a')) + abort(); + if (sizeof (char32_t) != sizeof (U'a')) + abort(); +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 03f42d3d167..4389f606c5c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2008-07-18 Kris Van Hees + Holger Hopp + + * config/abi/pre/gnu.ver: Support char16_t and char32_t. + * testsuite/util/testsuite_abi.cc (check_version): Add + CXXABI_1.3.3 to known_versions. + + 2008-07-16 Paolo Carlini * include/debug/vector (insert(iterator, _Tp&&), push_back(_Tp&&)): diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index a9c94fc694b..ced293a0dd1 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1012,3 +1012,15 @@ CXXABI_1.3.2 { _ZTIN10__cxxabiv119__foreign_exceptionE; } CXXABI_1.3.1; + +CXXABI_1.3.3 { + + # typeinfo for char16_t and char32_t + _ZTIu8char16_t; + _ZTIPu8char16_t; + _ZTIPKu8char16_t; + _ZTIu8char32_t; + _ZTIPu8char32_t; + _ZTIPKu8char32_t; + +} CXXABI_1.3.2; diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 6466fbabcd8..c15b8b24447 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -199,6 +199,7 @@ check_version(symbol& test, bool added) known_versions.push_back("CXXABI_1.3"); known_versions.push_back("CXXABI_1.3.1"); known_versions.push_back("CXXABI_1.3.2"); + known_versions.push_back("CXXABI_1.3.3"); known_versions.push_back("CXXABI_LDBL_1.3"); } compat_list::iterator begin = known_versions.begin(); -- 2.30.2