diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/complex_literals.h | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C | 7 |
8 files changed, 102 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c00f24c..2de63c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net> + + * cp-tree.h (UDLIT_OP_ANSI_PREFIX): Remove space. + * parser.c (cp_parser_operator()): Parse user-defined string + literal as literal operator. + 2013-06-28 Paolo Carlini <paolo.carlini@oracle.com> PR c++/57645 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d3dd494..3e8043a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4404,7 +4404,7 @@ extern GTY(()) vec<tree, va_gc> *local_classes; #define LAMBDANAME_PREFIX "__lambda" #define LAMBDANAME_FORMAT LAMBDANAME_PREFIX "%d" -#define UDLIT_OP_ANSI_PREFIX "operator\"\" " +#define UDLIT_OP_ANSI_PREFIX "operator\"\"" #define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s" #define UDLIT_OP_MANGLED_PREFIX "li" #define UDLIT_OP_MANGLED_FORMAT UDLIT_OP_MANGLED_PREFIX "%s" diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 281e163..6e8293b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12244,6 +12244,8 @@ cp_parser_operator (cp_parser* parser) { tree id = NULL_TREE; cp_token *token; + bool bad_encoding_prefix = false; + int string_len = 2; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -12443,10 +12445,20 @@ cp_parser_operator (cp_parser* parser) cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); return ansi_opname (ARRAY_REF); + case CPP_WSTRING: + string_len = 3; + case CPP_STRING16: + case CPP_STRING32: + string_len = 5; + case CPP_UTF8STRING: + string_len = 4; + bad_encoding_prefix = true; case CPP_STRING: if (cxx_dialect == cxx98) maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS); - if (TREE_STRING_LENGTH (token->u.value) > 2) + if (bad_encoding_prefix) + error ("invalid encoding prefix in literal operator"); + if (TREE_STRING_LENGTH (token->u.value) > string_len) { error ("expected empty string after %<operator%> keyword"); return error_mark_node; @@ -12464,15 +12476,49 @@ cp_parser_operator (cp_parser* parser) 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_WSTRING_USERDEF: + string_len = 3; + case CPP_STRING16_USERDEF: + case CPP_STRING32_USERDEF: + string_len = 5; + case CPP_UTF8STRING_USERDEF: + string_len = 4; + bad_encoding_prefix = true; case CPP_STRING_USERDEF: - error ("missing space between %<\"\"%> and suffix identifier"); - return error_mark_node; + if (cxx_dialect == cxx98) + maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS); + if (bad_encoding_prefix) + error ("invalid encoding prefix in literal operator"); + { + tree string_tree = USERDEF_LITERAL_VALUE (token->u.value); + if (TREE_STRING_LENGTH (string_tree) > string_len) + { + 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 (id != error_mark_node) + { + const char *name = IDENTIFIER_POINTER (id); + return cp_literal_operator_id (name); + } + else + return error_mark_node; + } default: /* Anything else is an error. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ab4a98..5c09364 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net> + + * g++.dg/cpp0x/udlit-nospace-neg.C: Adjust. + * g++.dg/cpp1y/udlit-enc-prefix-neg.C: New. + * g++.dg/cpp1y/udlit-userdef-string.C: New. + * g++.dg/cpp1y/complex_literals.h: New. + 2013-06-28 Paolo Carlini <paolo.carlini@oracle.com> PR c++/57645 diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C b/gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C index 2b57637..f06bd8b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C @@ -1,3 +1,5 @@ // { dg-options "-std=c++0x" } -float operator ""_abc(const char*); // { dg-error "missing space between|and suffix identifier" } +float operator ""_abc(const char*); + +int operator""_def(long double); diff --git a/gcc/testsuite/g++.dg/cpp1y/complex_literals.h b/gcc/testsuite/g++.dg/cpp1y/complex_literals.h new file mode 100644 index 0000000..ea328e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/complex_literals.h @@ -0,0 +1,12 @@ + +#include <complex> + +#pragma GCC system_header + +std::complex<float> +operator""if(long double ximag) +{ return std::complex<float>(0.0F, static_cast<float>(ximag)); } + +std::complex<float> +operator""if(unsigned long long nimag) +{ return std::complex<float>(0.0F, static_cast<float>(nimag)); } diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C b/gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C new file mode 100644 index 0000000..149fd0d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C @@ -0,0 +1,17 @@ +// { dg-options -std=c++1y } + +int +operator L""_Ls(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator u""_s16(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator U""_s32(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } + +int +operator u8""_u8s(unsigned long long) // { dg-error "invalid encoding prefix in literal operator" } +{ return 0; } diff --git a/gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C b/gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C new file mode 100644 index 0000000..e58a66b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C @@ -0,0 +1,7 @@ +// { dg-options -std=c++1y } + +#include "complex_literals.h" + +auto cx = 1.1if; + +auto cn = 123if; |