===================================================================
@@ -1895,7 +1895,7 @@
static tree cp_parser_identifier
(cp_parser *);
static tree cp_parser_string_literal
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, bool);
static tree cp_parser_userdef_char_literal
(cp_parser *);
static tree cp_parser_userdef_string_literal
@@ -3566,7 +3566,8 @@
FUTURE: ObjC++ will need to handle @-strings here. */
static tree
-cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
+cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
+ bool lookup_udlit = true)
{
tree value;
size_t count;
@@ -3721,7 +3722,10 @@
{
tree literal = build_userdef_literal (suffix_id, value,
OT_NONE, NULL_TREE);
- value = cp_parser_userdef_string_literal (literal);
+ if (lookup_udlit)
+ value = cp_parser_userdef_string_literal (literal);
+ else
+ value = literal;
}
}
else
@@ -12636,7 +12640,7 @@
{
tree id = NULL_TREE;
cp_token *token;
- bool bad_encoding_prefix = false;
+ bool utf8 = false;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -12836,83 +12840,73 @@
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
return ansi_opname (ARRAY_REF);
+ case CPP_UTF8STRING:
+ case CPP_UTF8STRING_USERDEF:
+ utf8 = true;
+ case CPP_STRING:
case CPP_WSTRING:
case CPP_STRING16:
case CPP_STRING32:
- case CPP_UTF8STRING:
- bad_encoding_prefix = true;
- /* Fall through. */
-
- case CPP_STRING:
- if (cxx_dialect == cxx98)
- maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
- if (bad_encoding_prefix)
- {
- error ("invalid encoding prefix in literal operator");
- return error_mark_node;
- }
- if (TREE_STRING_LENGTH (token->u.value) > 2)
- {
- error ("expected empty string after %<operator%> keyword");
- return error_mark_node;
- }
- /* Consume the string. */
- cp_lexer_consume_token (parser->lexer);
- /* Look for the suffix identifier. */
- token = cp_lexer_peek_token (parser->lexer);
- if (token->type == CPP_NAME)
- {
- id = cp_parser_identifier (parser);
- if (id != error_mark_node)
- {
- const char *name = IDENTIFIER_POINTER (id);
- return cp_literal_operator_id (name);
- }
- }
- else if (token->type == CPP_KEYWORD)
- {
- error ("unexpected keyword;"
- " remove space between quotes and suffix identifier");
- return error_mark_node;
- }
- else
- {
- error ("expected suffix identifier");
- return error_mark_node;
- }
-
+ case CPP_STRING_USERDEF:
case CPP_WSTRING_USERDEF:
case CPP_STRING16_USERDEF:
case CPP_STRING32_USERDEF:
- case CPP_UTF8STRING_USERDEF:
- bad_encoding_prefix = true;
- /* Fall through. */
+ {
+ tree str, string_tree;
+ int sz, len;
- case CPP_STRING_USERDEF:
- if (cxx_dialect == cxx98)
- maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
- if (bad_encoding_prefix)
- {
- error ("invalid encoding prefix in literal operator");
+ if (cxx_dialect == cxx98)
+ maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+
+ /* Consume the string. */
+ str = cp_parser_string_literal (parser, /*translate=*/true,
+ /*wide_ok=*/true, /*lookup_udlit=*/false);
+ if (str == error_mark_node)
return error_mark_node;
- }
- {
- tree string_tree = USERDEF_LITERAL_VALUE (token->u.value);
- if (TREE_STRING_LENGTH (string_tree) > 2)
+ else if (TREE_CODE (str) == USERDEF_LITERAL)
{
+ string_tree = USERDEF_LITERAL_VALUE (str);
+ id = USERDEF_LITERAL_SUFFIX_ID (str);
+ }
+ else
+ {
+ string_tree = str;
+ /* Look for the suffix identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME)
+ id = cp_parser_identifier (parser);
+ else if (token->type == CPP_KEYWORD)
+ {
+ error ("unexpected keyword;"
+ " remove space between quotes and suffix identifier");
+ return error_mark_node;
+ }
+ else
+ {
+ error ("expected suffix identifier");
+ return error_mark_node;
+ }
+ }
+ sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
+ (TREE_TYPE (TREE_TYPE (string_tree))));
+ len = TREE_STRING_LENGTH (string_tree) / sz - 1;
+ if (len != 0)
+ {
error ("expected empty string after %<operator%> keyword");
return error_mark_node;
}
- id = USERDEF_LITERAL_SUFFIX_ID (token->u.value);
- /* Consume the user-defined string literal. */
- cp_lexer_consume_token (parser->lexer);
+ if (utf8 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string_tree)))
+ != char_type_node)
+ {
+ error ("invalid encoding prefix in literal operator");
+ return error_mark_node;
+ }
if (id != error_mark_node)
{
const char *name = IDENTIFIER_POINTER (id);
- return cp_literal_operator_id (name);
+ id = cp_literal_operator_id (name);
}
- else
- return error_mark_node;
+ return id;
}
default:
===================================================================
@@ -0,0 +1,28 @@
+// PR c++/60209
+// { dg-do compile { target c++11 } }
+
+// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1473
+
+void operator "" "boo" _ya(unsigned long long); // { dg-error "expected empty string after" }
+
+void operator "" "boo"_ya(unsigned long long); // { dg-error "expected empty string after" }
+
+void operator "" u"" _u(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" }
+
+void operator u"" "" _v(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" }
+
+void operator U"" "" _w(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" }
+
+void operator L"" "" _x(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" }
+
+void operator u8"" "" _y(unsigned long long); // { dg-error "invalid encoding prefix in literal operator" }
+
+void operator u"" L"" _z(unsigned long long); // { dg-error "unsupported non-standard concatenation of string literals" }
+
+void operator ""_p ""_q(unsigned long long); // { dg-error "inconsistent user-defined literal suffixes" }
+
+void operator "" "" while(unsigned long long); // { dg-error "unexpected keyword; remove space between quotes and suffix identifier" }
+
+void operator "" ""(unsigned long long); // { dg-error "expected suffix identifier" }
+
+// { dg-error "invalid encoding prefix in literal operator" "invalid" { target *-*-* } 20 }
===================================================================
@@ -0,0 +1,12 @@
+// PR c++/60209
+// { dg-do compile { target c++11 } }
+
+// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1473
+
+void operator "" "" _x(unsigned long long);
+
+void operator "" "" "" _x(unsigned long long);
+
+void operator "" ""_w(unsigned long long);
+
+void operator "" ""_w ""(unsigned long long);
===================================================================
@@ -5,17 +5,17 @@
{ return 0; }
int
-operator L"*"_Ls(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" }
+operator L"*"_Ls(unsigned long long) // { dg-error "expected empty string after 'operator'" }
{ return 0; }
int
-operator u"*"_s16(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" }
+operator u"*"_s16(unsigned long long) // { dg-error "expected empty string after 'operator'" }
{ return 0; }
int
-operator U"*"_s32(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" }
+operator U"*"_s32(unsigned long long) // { dg-error "expected empty string after 'operator'" }
{ return 0; }
int
-operator u8"*"_u8s(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" }
+operator u8"*"_u8s(unsigned long long) // { dg-error "expected empty string after 'operator'" }
{ return 0; }