Hi,

in this old rejects-valid we reject:

struct s
{
  typedef void f(void);
  f operator();
};

at the beginning of grokdeclarator:

  if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
       && innermost_code != cdk_function
       && ! (ctype && !declspecs->any_specifiers_p))
     {

It seems to me that we can simply remove the check, because a bit later we have:

  /* Only functions may be declared using an operator-function-id. */
  if (unqualified_id
      && IDENTIFIER_OPNAME_P (unqualified_id)
      && TREE_CODE (type) != FUNCTION_TYPE
      && TREE_CODE (type) != METHOD_TYPE)
    {

which uses type and is more precise. Tested x86_64-linux.

Thanks!
Paolo.

///////////////////

/cp
2014-06-24  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/33972
        * decl.c (grokdeclarator): Do not early check for operator-function-id
        as non-function.

/testsuite
2014-06-24  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/33972
        * g++.dg/other/operator3.C: New.
        * g++.dg/template/operator8.C: Adjust.
        * g++.dg/template/operator9.C: Likewise.
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 211931)
+++ cp/decl.c   (working copy)
@@ -9007,7 +9007,7 @@ grokdeclarator (const cp_declarator *declarator,
       return error_mark_node;
     }
 
-  if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
+  if (flags == TYPENAME_FLAG
       && innermost_code != cdk_function
       && ! (ctype && !declspecs->any_specifiers_p))
     {
Index: testsuite/g++.dg/other/operator3.C
===================================================================
--- testsuite/g++.dg/other/operator3.C  (revision 0)
+++ testsuite/g++.dg/other/operator3.C  (working copy)
@@ -0,0 +1,7 @@
+// PR c++/33972
+
+struct s
+{
+  typedef void f(void);
+  f operator();
+};
Index: testsuite/g++.dg/template/operator8.C
===================================================================
--- testsuite/g++.dg/template/operator8.C       (revision 211931)
+++ testsuite/g++.dg/template/operator8.C       (working copy)
@@ -2,5 +2,5 @@
 
 struct A
 {
-    template<operator+> void foo() {}   // { dg-error 
"identifier|non-function|template arguments" }
+    template<operator+> void foo() {}   // { dg-error 
"identifier|parameter|template arguments" }
 };
Index: testsuite/g++.dg/template/operator9.C
===================================================================
--- testsuite/g++.dg/template/operator9.C       (revision 211931)
+++ testsuite/g++.dg/template/operator9.C       (working copy)
@@ -1,6 +1,6 @@
 //PR c++/27670
 
-template<operator+> void foo(); // { dg-error "before|non-function|template" }
+template<operator+> void foo(); // { dg-error "before|parameter|template" }
 
 void bar()
 {

Reply via email to