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.

////////////////////////
/cp
2013-07-25  Paolo Carlini  <paolo.carl...@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.carl...@oracle.com>

        PR c++/57880
        * g++.dg/cpp1y/udlit-empty-string-neg.C: New.
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; }

Reply via email to