[C++ Patch] PR 57880

Paolo Carlini paolo.carlini@oracle.com
Wed Jul 24 22:30:00 GMT 2013


Hi,

submitter ran a static analysis tool on parser.c and found in the main 
switch of cp_parser_operator some broken cases having to do with user 
defined literals. When I looked into it I found a rather convoluted 
logic which tried to possibly emit *both* the error message for and 
invalid encoding prefix (as tested in udlit-enc-prefix-neg.C) and the 
error message for non-empty string after 'operator' (untested in the 
testsuite) before returning error_mark_node. Then when only the former 
was appropriate, it was emitted twice. The second missed cases - too big 
string_len.

Now, I don't think it should be so common that the user code has both 
issues in the same user defined literal (in that case providing both 
error messages at once would make debugging quicker), thus in the below 
I decided to simplify everything and immediately return error_mark_node 
after any error along the way.

Tested x86_64-linux.

Thanks,
Paolo.

////////////////////////
-------------- next part --------------
/cp
2013-07-25  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57880
	* parser.c (cp_parser_operator, case CPP_WSTRING, CPP_STRING16,
	CPP_STRING32, CPP_UTF8STRING, CPP_WSTRING_USERDEF,
	CPP_STRING16_USERDEF, CPP_STRING32_USERDEF, CPP_UTF8STRING_USERDEF):
	Fix string_len management, tidy.

/testsuite
2013-07-25  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57880
	* g++.dg/cpp1y/udlit-empty-string-neg.C: New.
-------------- next part --------------
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 201214)
+++ cp/parser.c	(working copy)
@@ -12261,7 +12261,6 @@ 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);
@@ -12462,20 +12461,22 @@ cp_parser_operator (cp_parser* parser)
       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;
+     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");
-      if (TREE_STRING_LENGTH (token->u.value) > string_len)
 	{
+	  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;
 	}
@@ -12505,21 +12506,23 @@ cp_parser_operator (cp_parser* parser)
 	}
 
     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;
+      /* Fall through.  */
+
     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");
+	{
+	  error ("invalid encoding prefix in literal operator");
+	  return error_mark_node;
+	}
       {
 	tree string_tree = USERDEF_LITERAL_VALUE (token->u.value);
-	if (TREE_STRING_LENGTH (string_tree) > string_len)
+	if (TREE_STRING_LENGTH (string_tree) > 2)
 	  {
 	    error ("expected empty string after %<operator%> keyword");
 	    return error_mark_node;
Index: testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C
===================================================================
--- testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/udlit-empty-string-neg.C	(working copy)
@@ -0,0 +1,5 @@
+// { dg-options -std=c++1y }
+
+int
+operator "*"_s(unsigned long long) // { dg-error "expected empty string after 'operator'" }
+{ return 0; }


More information about the Gcc-patches mailing list