On 10/25/2013 10:40 AM, Jakub Jelinek wrote:
On Fri, Oct 25, 2013 at 10:29:41AM -0400, Ed Smith-Rowland wrote:
2013-10-25 Edward Smith-Rowland <3dw...@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-10-25 Edward Smith-Rowland <3dw...@verizon.net>
PR c++/58708
*g++.dg/cpp1y/pr58708.C : New.
--- testsuite/g++.dg/cpp1y/pr58708.C (revision 0)
+++ testsuite/g++.dg/cpp1y/pr58708.C (working copy)
@@ -0,0 +1,91 @@
+// { dg-options -std=c++1y }
+// { dg-do run }
+
+template<typename _Tp, _Tp __v>
+ struct integral_constant
+ {
+ static constexpr _Tp value = __v;
+ typedef _Tp value_type;
+ typedef integral_constant<_Tp, __v> type;
+ constexpr operator value_type() const { return value; }
+ constexpr value_type operator()() const { return value; }
+ };
+
+template<typename _Tp, _Tp __v>
+ constexpr _Tp integral_constant<_Tp, __v>::value;
+
+typedef integral_constant<bool, true> true_type;
+
+typedef integral_constant<bool, false> false_type;
+
+template<typename, typename>
+ struct is_same
+ : public false_type { };
+
+template<typename _Tp>
+ struct is_same<_Tp, _Tp>
+ : public true_type { };
Why not just the minimal:
template< class T, class U >
struct is_same {
static constexpr bool value = false;
};
template< class T >
struct is_same<T, T> {
static constexpr bool value = true;
};
other tests are using?
Jakub
All,
Here is a new patch. It's the same patch but a lighter testcase.
Built and tested on x86_64-linux.
OK?
Ed
gcc/cp:
2013-10-31 Edward Smith-Rowland <3dw...@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-10-31 Edward Smith-Rowland <3dw...@verizon.net>
PR c++/58708
*g++.dg/cpp1y/pr58708.C : New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 203997)
+++ cp/parser.c (working copy)
@@ -3793,22 +3793,39 @@
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;
Index: testsuite/g++.dg/cpp1y/pr58708.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr58708.C (revision 0)
+++ testsuite/g++.dg/cpp1y/pr58708.C (working copy)
@@ -0,0 +1,60 @@
+// { dg-options -std=c++1y }
+// { dg-do run }
+
+template<typename, typename>
+ struct is_same
+ {
+ static constexpr bool value = false;
+ };
+
+template<typename _Tp>
+ struct is_same<_Tp, _Tp>
+ {
+ static constexpr bool value = true;
+ };
+
+template<typename CharT, CharT... Str>
+ struct Foo
+ {
+ using char_type = CharT;
+ char_type chars[sizeof...(Str)]{Str...};
+ };
+
+template<typename CharT, CharT... Str>
+ Foo<CharT, Str...>
+ operator""_foo()
+ {
+ return Foo<CharT, Str...>();
+ }
+
+int
+main()
+{
+ auto fooU = U"\x10000\x10001\x10002"_foo;
+ if (is_same<decltype(fooU)::char_type, char32_t>::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<decltype(foo)::char_type, char>::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<decltype(wfoo)::char_type, wchar_t>::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<decltype(foou)::char_type, char16_t>::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();
+}