diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cc988333108..ce67fcd7aa8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-06-30 Edward Smith-Rowland <3dw4rd@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! + 2014-06-30 Jason Merrill PR c++/61659 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 013fc6ecd08..8ff57c7658e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1899,7 +1899,7 @@ static tree cp_parser_string_literal 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 *); @@ -3721,8 +3721,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) { 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 @@ -3970,9 +3969,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) 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); @@ -23224,10 +23222,17 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ok = false; } if (!ok) - error ("literal operator template %qD has invalid parameter list." - " Expected non-type template argument pack " - " or ", - decl); + { + if (cxx_dialect >= cxx1y) + error ("literal operator template %qD has invalid parameter list." + " Expected non-type template argument pack " + " or ", + decl); + else + error ("literal operator template %qD has invalid parameter list." + " Expected non-type template argument pack ", + decl); + } } /* Register member declarations. */ if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf35498a3aa..6c819425f6e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2014-06-30 Edward Smith-Rowland <3dw4rd@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. + 2014-06-30 Bill Schmidt * gfortran.dg/round_4.f90: Skip for powerpc*-*-linux* since the diff --git a/gcc/testsuite/g++.dg/cpp0x/pr58781.C b/gcc/testsuite/g++.dg/cpp0x/pr58781.C new file mode 100644 index 00000000000..58c972f90f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr58781.C @@ -0,0 +1,18 @@ +// PR c++/58781 +// { dg-do compile { target c++11 } } + +#include + +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); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/pr60249.C b/gcc/testsuite/g++.dg/cpp0x/pr60249.C new file mode 100644 index 00000000000..e650dcb452b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr60249.C @@ -0,0 +1,6 @@ +// PR c++/60249 +// { dg-do compile { target c++11 } } + +decltype(""_) x; // { dg-error "unable to find string literal operator" } + +// { dg-error "invalid type in declaration before" "invalid" { target *-*-* } 4 } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr59867.C b/gcc/testsuite/g++.dg/cpp1y/pr59867.C new file mode 100644 index 00000000000..0f27a2056fd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr59867.C @@ -0,0 +1,52 @@ +// PR c++/59867 +// { dg-do compile { target c++14 } } + +#include +using namespace std; + +// constant +template + struct meta_value + { + typedef meta_value type; + typedef T value_type; + static const T value = x; + }; + +// array +template + struct meta_array + { + typedef meta_array type; + typedef T item_type; + }; + +// static array -> runtime array conversion utility +template + struct array_gen; + +template + struct array_gen> + { + static const T value[sizeof...(xs)]; + }; + +template + const T + array_gen>::value[sizeof...(xs)] = {xs...}; + +// static string +template + constexpr meta_array + operator""_s() + { + static_assert(sizeof...(xs) == 3, "What's wrong with you?"); + return meta_array(); + } + +int +main() +{ + auto a = "123"_s; + const char (& xs)[3] = array_gen::value; +}