Patchwork [C++] DR1473 - let literal operators be defined with empty user-defined string literal

login
register
mail settings
Submitter Ed Smith-Rowland
Date June 25, 2013, 12:27 p.m.
Message ID <51C98CCE.5060800@verizon.net>
Download mbox | patch
Permalink /patch/254136/
State New
Headers show

Comments

Ed Smith-Rowland - June 25, 2013, 12:27 p.m.
This will allow such things as
   constexpr std::complex<float>
   operator""if(long double imag);

OK after testing completes on x86_64-linux.

Ed
gcc/cp:

2013-06-25  Ed Smith-Rowland  <3dw4rd@verizon.net>

	* gcc/cp/parser.c (cp_parser_operator()): Parse user-defined string
	literal as literal operator.


gcc/testsuite:

2013-06-25  Ed Smith-Rowland  <3dw4rd@verizon.net>

	* gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C: Adjust.
	* gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C: New.
	* gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C: New.
Jason Merrill - June 25, 2013, 12:50 p.m.
On 06/25/2013 08:27 AM, Ed Smith-Rowland wrote:
> +      else if (token->type == CPP_KEYWORD)
> +	{
> +	  error ("unexpected keyword;"
> +		 " Remove space between quotes and suffix identifier");
> +	  return error_mark_node;
> +	}

Lower-case 'r' after a semicolon.

After giving the error, let's try to handle it properly anyway to avoid 
cascading errors.

> +	if (TREE_STRING_LENGTH (string_tree) > 2)

Why 2?  I would expect TREE_STRING_LENGTH for "" to be 1 (the NUL).

> +	    error ("expected empty string after %<operator%> keyword");
> +	    return error_mark_node;

And let's continue after the error here, too.

> +      error ("invalid encoding prefix in literal operator");
>        return error_mark_node;

And here.

Jason

Patch

Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 200342)
+++ gcc/cp/parser.c	(working copy)
@@ -12591,6 +12589,12 @@ 
 	      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");
@@ -12598,7 +12602,32 @@ 
 	}
 
     case CPP_STRING_USERDEF:
-      error ("missing space between %<\"\"%> and suffix identifier");
+      if (cxx_dialect == cxx98)
+	maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+      {
+	tree string_tree = USERDEF_LITERAL_VALUE (token->u.value);
+	if (TREE_STRING_LENGTH (string_tree) > 2)
+	  {
+	    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;
+      }
+
+    case CPP_WSTRING_USERDEF:
+    case CPP_STRING16_USERDEF:
+    case CPP_STRING32_USERDEF:
+    case CPP_UTF8STRING_USERDEF:
+      error ("invalid encoding prefix in literal operator");
       return error_mark_node;
 
     default:
Index: gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C	(revision 200342)
+++ gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C	(working copy)
@@ -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);
Index: gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C	(working copy)
@@ -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; }
Index: gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C	(working copy)
@@ -0,0 +1,7 @@ 
+// { dg-options -std=c++1y }
+
+#include "complex_literals.h"
+
+auto cx = 1.1if;
+
+auto cn = 123if;