aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEdward Smith-Rowland <3dw4rd@verizon.net>2014-07-13 13:36:57 +0000
committerEdward Smith-Rowland <emsr@gcc.gnu.org>2014-07-13 13:36:57 +0000
commitc6abdc366af68c28e3e8da236dfa7037be38971e (patch)
treecd2e3b27e59a076806ec50f18f9806df1388208c /gcc
parentca631fc2a4a08e2910c2b643fa1428b07ccdbb29 (diff)
downloadgcc-c6abdc366af68c28e3e8da236dfa7037be38971e.zip
gcc-c6abdc366af68c28e3e8da236dfa7037be38971e.tar.gz
gcc-c6abdc366af68c28e3e8da236dfa7037be38971e.tar.bz2
PR C++/60209 - Declaration of user-defined literal operator cause error
cp/ 2014-07-13 Edward Smith-Rowland <3dw4rd@verizon.net> PR C++/60209 - Declaration of user-defined literal operator cause error * cp/parser.c (cp_parser_operator()): Fold treatment of strings and user-defined string literals. Use the full string parser. (cp_parser_string_literal()): Add flag to not look for literal operator. testsuite/ 2014-07-13 Edward Smith-Rowland <3dw4rd@verizon.net> PR C++/60209 - Declaration of user-defined literal operator cause error * g++.dg/cpp0x/pr60209-neg.C: New. * g++.dg/cpp0x/pr60209.C: New. * g++.dg/cpp1y/udlit-empty-string-neg.C: Adjust messages. From-SVN: r212494
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c124
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr60209.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C8
6 files changed, 117 insertions, 69 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 88d7c85..e873d99 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2014-07-13 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ PR C++/60209 - Declaration of user-defined literal operator cause error
+ * cp/parser.c (cp_parser_operator()): Fold treatment of strings
+ and user-defined string literals. Use the full string parser.
+ (cp_parser_string_literal()): Add flag to not look for literal operator.
+
2014-07-11 Jason Merrill <jason@redhat.com>
PR c++/22434
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 72f987e..b260b24 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1895,7 +1895,7 @@ static cp_parser *cp_parser_new
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 @@ cp_parser_identifier (cp_parser* parser)
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 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
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 @@ cp_parser_operator (cp_parser* parser)
{
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_operator (cp_parser* parser)
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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fa4baa5..ac43425 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2014-07-13 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ PR C++/60209 - Declaration of user-defined literal operator cause error
+ * g++.dg/cpp0x/pr60209-neg.C: New.
+ * g++.dg/cpp0x/pr60209.C: New.
+ * g++.dg/cpp1y/udlit-empty-string-neg.C: Adjust messages.
+
2014-07-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60967
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C b/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C
new file mode 100644
index 0000000..77fd3d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr60209.C b/gcc/testsuite/g++.dg/cpp0x/pr60209.C
new file mode 100644
index 0000000..6ed26e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr60209.C
@@ -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);
diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C b/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C
index 7c23641..4f1a34a 100644
--- a/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C
@@ -5,17 +5,17 @@ operator "*"_s(unsigned long long) // { dg-error "expected empty string after 'o
{ 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; }