On 06/27/2014 05:39 PM, paolo.carlini at oracle dot com wrote:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60249

--- Comment #5 from Paolo Carlini <paolo.carlini at oracle dot com> ---
Patch looks *great*. If it works, please send it to mailing list ASAP.

I think I finally got these weird user-defined string literal bugs. "Don't cross the streams!"

Dr. Egon Spengler

PR C++/58781  <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58781>  - Unicode 
strings broken in a strange way
PR C++/59867  <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59867>  - Template 
string literal loses first symbol
PR C++/60249  <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60249>  - Compiler 
goes into semi-infinite loop with wrong usage of user defined string literals
Plus I fixed an misleading error message for string literal operator templates 
(not available in C++11).

Built and tested clean on x86_64-linux.

OK?

I would also like to apply this to 4.9.

cp/

2014-06-28  Edward Smith-Rowland  <3dw...@verizon.net>

        PR c++/58781
        PR c++/60249
        PR c++/59867
        * parser.c (cp_parser_userdef_string_literal()): Take a tree
        not a cp_token*. (cp_parser_string_literal(): Don't hack
        the token stream!


testsuite/

2014-06-28  Edward Smith-Rowland  <3dw...@verizon.net>

        PR c++/58781
        PR c++/60249
        PR c++/59867
        * testsuite/g++.dg/cpp0x/pr58781.C: New.
        * testsuite/g++.dg/cpp0x/pr60249.C: New.
        * testsuite/g++.dg/cpp1y/pr59867.C: New.

Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 211481)
+++ cp/parser.c (working copy)
@@ -1893,7 +1893,7 @@
 static tree cp_parser_userdef_char_literal
   (cp_parser *);
 static tree cp_parser_userdef_string_literal
-  (cp_token *);
+  (tree);
 static tree cp_parser_userdef_numeric_literal
   (cp_parser *);
 
@@ -3713,8 +3713,7 @@
        {
          tree literal = build_userdef_literal (suffix_id, value,
                                                OT_NONE, NULL_TREE);
-         tok->u.value = literal;
-         return cp_parser_userdef_string_literal (tok);
+         value = cp_parser_userdef_string_literal (literal);
        }
     }
   else
@@ -3962,9 +3961,8 @@
    as arguments.  */
 
 static tree
-cp_parser_userdef_string_literal (cp_token *token)
+cp_parser_userdef_string_literal (tree literal)
 {
-  tree literal = token->u.value;
   tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
   tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
   tree value = USERDEF_LITERAL_VALUE (literal);
@@ -23156,10 +23154,17 @@
            ok = false;
        }
       if (!ok)
-       error ("literal operator template %qD has invalid parameter list."
-              "  Expected non-type template argument pack <char...>"
-              " or <typename CharT, CharT...>",
-              decl);
+       {
+         if (cxx_dialect >= cxx1y)
+           error ("literal operator template %qD has invalid parameter list."
+                  "  Expected non-type template argument pack <char...>"
+                  " or <typename CharT, CharT...>",
+                  decl);
+         else
+           error ("literal operator template %qD has invalid parameter list."
+                  "  Expected non-type template argument pack <char...>",
+                  decl);
+       }
     }
   /* Register member declarations.  */
   if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
Index: testsuite/g++.dg/cpp0x/pr58781.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr58781.C    (revision 0)
+++ testsuite/g++.dg/cpp0x/pr58781.C    (revision 0)
@@ -0,0 +1,18 @@
+// PR c++/58781
+// { dg-do compile { target c++11 } }
+
+#include <cstddef>
+
+int
+operator""_s(const char32_t *a, size_t b)
+{
+  return 0;
+}
+
+int
+f()
+{
+  using a = decltype(U"\x1181"_s);
+  using b = decltype(U"\x8111"_s);
+  using c = decltype(U" \x1181"_s);
+}
Index: testsuite/g++.dg/cpp0x/pr60249.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr60249.C    (revision 0)
+++ testsuite/g++.dg/cpp0x/pr60249.C    (revision 0)
@@ -0,0 +1,4 @@
+// PR c++/60249
+// { dg-do compile { target c++11 } }
+
+decltype(""_) x;
Index: testsuite/g++.dg/cpp1y/pr59867.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr59867.C    (revision 0)
+++ testsuite/g++.dg/cpp1y/pr59867.C    (revision 0)
@@ -0,0 +1,52 @@
+// PR c++/59867
+// { dg-do compile { target c++14 } }
+
+#include <iostream>
+using namespace std;
+
+// constant
+template<typename T, T x>
+  struct meta_value
+  {
+    typedef meta_value type;
+    typedef T value_type;
+    static const T value = x;
+  };
+
+// array
+template<typename T, T... data>
+  struct meta_array
+  {
+    typedef meta_array type;
+    typedef T item_type;
+  };
+
+// static array -> runtime array conversion utility
+template<typename T>
+  struct array_gen;
+
+template<typename T, T... xs>
+  struct array_gen<meta_array<T, xs...>>
+  {
+    static const T value[sizeof...(xs)];
+  };
+
+template<typename T, T... xs>
+  const T
+  array_gen<meta_array<T, xs...>>::value[sizeof...(xs)] = {xs...};
+
+// static string
+template<typename T, T... xs>
+  constexpr meta_array<T, xs...>
+  operator""_s()
+  {
+    static_assert(sizeof...(xs) == 3, "What's wrong with you?");
+    return meta_array<T, xs...>();
+  }
+
+int
+main()
+{
+  auto a = "123"_s;
+  const char (& xs)[3] = array_gen<decltype("123"_s)>::value;
+}

Reply via email to