diff options
author | Edward Smith-Rowland <3dw4rd@verizon.net> | 2014-07-13 13:36:57 +0000 |
---|---|---|
committer | Edward Smith-Rowland <emsr@gcc.gnu.org> | 2014-07-13 13:36:57 +0000 |
commit | c6abdc366af68c28e3e8da236dfa7037be38971e (patch) | |
tree | cd2e3b27e59a076806ec50f18f9806df1388208c | |
parent | ca631fc2a4a08e2910c2b643fa1428b07ccdbb29 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 124 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr60209-neg.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr60209.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C | 8 |
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; } |