Here is a patch to correct the char type and the type, number of nontype
parameter pack for user defined strng literal operator templates.
Bootstrapped and tested on x86_64-linux.
OK?
gcc/cp:
2013-10-17 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-17 Edward Smith-Rowland <3dw...@verizon.net>
PR c++/58708
*g++.dg/cpp1y/pr58708.C : New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 203739)
+++ cp/parser.c (working copy)
@@ -3792,22 +3792,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;
@@ -21425,6 +21442,9 @@
/* C++11 noreturn attribute is equivalent to GNU's. */
if (is_attribute_p ("noreturn", attr_id))
TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu");
+ /* C++14 deprecated attribute is equivalent to GNU's. */
+ else if (cxx_dialect >= cxx1y && is_attribute_p ("deprecated", attr_id))
+ TREE_PURPOSE (TREE_PURPOSE (attribute)) = get_identifier ("gnu");
}
/* Now parse the optional argument clause of the attribute. */
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,70 @@
+// { dg-options -std=c++1y }
+
+#include <array>
+#include <vector>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+struct Foo
+{
+ std::array<bool, 4> type;
+ std::array<bool, 4> const_type;
+ std::vector<int> chars;
+};
+
+template<typename CharT, CharT... str>
+Foo
+operator""_foo()
+{
+ CharT arr[]{str...};
+
+ Foo foo;
+
+ foo.type[0] = std::is_same<CharT, char>::value;
+ foo.type[1] = std::is_same<CharT, wchar_t>::value;
+ foo.type[2] = std::is_same<CharT, char16_t>::value;
+ foo.type[3] = std::is_same<CharT, char32_t>::value;
+ foo.const_type[0] = std::is_same<CharT, const char>::value;
+ foo.const_type[1] = std::is_same<CharT, const wchar_t>::value;
+ foo.const_type[2] = std::is_same<CharT, const char16_t>::value;
+ foo.const_type[3] = std::is_same<CharT, const char32_t>::value;
+
+ for(CharT c : arr)
+ foo.chars.push_back((int)c);
+
+ return foo;
+}
+
+int
+main()
+{
+ Foo foo;
+
+ foo = U"\x10000\x10001\x10002"_foo;
+ VERIFY (foo.type[3] == true);
+ VERIFY (foo.chars.size() == 3);
+ VERIFY (foo.chars[0] == 65536);
+ VERIFY (foo.chars[1] == 65537);
+ VERIFY (foo.chars[2] == 65538);
+
+ foo = "\x61\x62\x63"_foo;
+ VERIFY (foo.type[0] == true);
+ VERIFY (foo.chars.size() == 3);
+ VERIFY (foo.chars[0] == 97);
+ VERIFY (foo.chars[1] == 98);
+ VERIFY (foo.chars[2] == 99);
+
+ foo = L"\x01020304\x05060708"_foo;
+ VERIFY (foo.type[1] == true);
+ VERIFY (foo.chars.size() == 2);
+ VERIFY (foo.chars[0] == 16909060);
+ VERIFY (foo.chars[1] == 84281096);
+
+ foo = u"\x0102\x0304\x0506\x0708"_foo;
+ VERIFY (foo.type[2] == true);
+ VERIFY (foo.chars.size() == 4);
+ VERIFY (foo.chars[0] == 258);
+ VERIFY (foo.chars[1] == 772);
+ VERIFY (foo.chars[2] == 1286);
+ VERIFY (foo.chars[3] == 1800);
+}