From 1b877311222c05bd8a3e5df2518d514f32a0102e Mon Sep 17 00:00:00 2001 From: emsr Date: Fri, 1 Nov 2013 23:00:48 +0000 Subject: [PATCH] gcc/cp: 2013-11-01 Edward Smith-Rowland <3dw4rd@verizon.net> PR c++/58708 * parser.c (make_string_pack): Discover non-const type and size of character and build parm pack with correct type and chars. gcc/testsuite: 2013-11-01 Edward Smith-Rowland <3dw4rd@verizon.net> PR c++/58708 * g++.dg/cpp1y/pr58708.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204305 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/parser.c | 29 +++++++++++++---- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/cpp1y/pr58708.C | 60 ++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr58708.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d707fec81f1..707b9495560 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-11-01 Edward Smith-Rowland <3dw4rd@verizon.net> + + PR c++/58708 + * parser.c (make_string_pack): Discover non-const type and size + of character and build parm pack with correct type and chars. + 2013-11-01 Trevor Saunders * semantics.c (build_anon_member_initialization): Convert fields to be diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bbc8e751a87..d55f5f9c786 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3793,22 +3793,39 @@ make_string_pack (tree value) tree charvec; tree argpack = make_node (NONTYPE_ARGUMENT_PACK); const char *str = TREE_STRING_POINTER (value); - int i, len = TREE_STRING_LENGTH (value) - 1; + int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))); + int len = TREE_STRING_LENGTH (value) / sz - 1; tree argvec = make_tree_vec (2); - tree string_char_type_node = TREE_TYPE (TREE_TYPE (value)); + tree str_char_type_node = TREE_TYPE (TREE_TYPE (value)); + str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node); /* First template parm is character type. */ - TREE_VEC_ELT (argvec, 0) = string_char_type_node; + TREE_VEC_ELT (argvec, 0) = str_char_type_node; /* Fill in CHARVEC with all of the parameters. */ charvec = make_tree_vec (len); - for (i = 0; i < len; ++i) - TREE_VEC_ELT (charvec, i) = build_int_cst (string_char_type_node, str[i]); + if (sz == 1) + { + for (int i = 0; i < len; ++i) + TREE_VEC_ELT (charvec, i) = build_int_cst (str_char_type_node, str[i]); + } + else if (sz == 2) + { + const uint16_t *num = (const uint16_t *)str; + for (int i = 0; i < len; ++i) + TREE_VEC_ELT (charvec, i) = build_int_cst (str_char_type_node, num[i]); + } + else if (sz == 4) + { + const uint32_t *num = (const uint32_t *)str; + for (int i = 0; i < len; ++i) + TREE_VEC_ELT (charvec, i) = build_int_cst (str_char_type_node, num[i]); + } /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, charvec); - TREE_TYPE (argpack) = string_char_type_node; + TREE_TYPE (argpack) = str_char_type_node; TREE_VEC_ELT (argvec, 1) = argpack; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e9bd852816f..75975d0be10 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-01 Edward Smith-Rowland <3dw4rd@verizon.net> + + PR c++/58708 + * g++.dg/cpp1y/pr58708.C: New. + 2013-11-01 Marc Glisse PR c++/58834 diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58708.C b/gcc/testsuite/g++.dg/cpp1y/pr58708.C new file mode 100644 index 00000000000..a9c19ebb6c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr58708.C @@ -0,0 +1,60 @@ +// { dg-options -std=c++1y } +// { dg-do run } + +template + struct is_same + { + static constexpr bool value = false; + }; + +template + struct is_same<_Tp, _Tp> + { + static constexpr bool value = true; + }; + +template + struct Foo + { + using char_type = CharT; + char_type chars[sizeof...(Str)]{Str...}; + }; + +template + Foo + operator""_foo() + { + return Foo(); + } + +int +main() +{ + auto fooU = U"\x10000\x10001\x10002"_foo; + if (is_same::value != true) __builtin_abort(); + if (sizeof(fooU.chars)/sizeof(char32_t) != 3) __builtin_abort(); + if (fooU.chars[0] != 65536) __builtin_abort(); + if (fooU.chars[1] != 65537) __builtin_abort(); + if (fooU.chars[2] != 65538) __builtin_abort(); + + auto foo = "\x61\x62\x63"_foo; + if (is_same::value != true) __builtin_abort(); + if (sizeof(foo.chars)/sizeof(char) != 3) __builtin_abort(); + if (foo.chars[0] != 97) __builtin_abort(); + if (foo.chars[1] != 98) __builtin_abort(); + if (foo.chars[2] != 99) __builtin_abort(); + + auto wfoo = L"\x01020304\x05060708"_foo; + if (is_same::value != true) __builtin_abort(); + if (sizeof(wfoo.chars)/sizeof(wchar_t) != 2) __builtin_abort(); + if (wfoo.chars[0] != 16909060) __builtin_abort(); + if (wfoo.chars[1] != 84281096) __builtin_abort(); + + auto foou = u"\x0102\x0304\x0506\x0708"_foo; + if (is_same::value != true) __builtin_abort(); + if (sizeof(foou.chars)/sizeof(char16_t) != 4) __builtin_abort(); + if (foou.chars[0] != 258) __builtin_abort(); + if (foou.chars[1] != 772) __builtin_abort(); + if (foou.chars[2] != 1286) __builtin_abort(); + if (foou.chars[3] != 1800) __builtin_abort(); +} -- 2.11.4.GIT