aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.c52
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/complex_literals.h12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C7
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;