Hi,

On 08/08/19 16:51, Jason Merrill wrote:
On 8/6/19 8:28 AM, Paolo Carlini wrote:
apparently this is now easy to do, likely because a while ago I made sure that we consistently have meaningful locations for TYPE_DECLs too.

(I went through grokdeclarator and confirmed that when the third argument is FUNCDEF or MEMFUNCDEF it cannot return NULL_TREE)

-typedef void foo () {}    // { dg-error "invalid function declaration" } +typedef void foo () {}    // { dg-error "14:invalid function declaration" }
 struct S
 {
-  typedef int bar (void) { return 0; } // { dg-error "invalid member function declaration" } +  typedef int bar (void) { return 0; }  // { dg-error "15:invalid member function declaration" }

Maybe we could give a more specific diagnostic in grokdeclarator; perhaps under

  if (typedef_p && decl_context != TYPENAME)

complain and return error_mark_node in FUNCDEF or MEMFUNCDEF context.

Yes, I briefly considered that myself, I only stopped because grokdeclarator seemed big enough already ;)

Anyway, I tested on x86_64-linux the below. Not 100% sure about the wording, but we have something similar a few lines below. Also, probably a single error_at both for functions and member functions would be good enough (but it would be a specificity regression).

Thanks, Paolo.

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

Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 274220)
+++ cp/decl.c   (working copy)
@@ -12165,6 +12165,17 @@ grokdeclarator (const cp_declarator *declarator,
       bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias);
       tree decl;
 
+      if (funcdef_flag)
+       {
+         if (decl_context == NORMAL)
+           error_at (id_loc,
+                     "typedef may not be a function definition");
+         else
+           error_at (id_loc,
+                     "typedef may not be a member function definition");
+         return error_mark_node;
+       }
+
       /* This declaration:
 
           typedef void f(int) const;
@@ -15775,13 +15786,6 @@ start_function (cp_decl_specifier_seq *declspecs,
   invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
   if (decl1 == error_mark_node)
     return false;
-  /* If the declarator is not suitable for a function definition,
-     cause a syntax error.  */
-  if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
-    {
-      error ("invalid function declaration");
-      return false;
-    }
 
   if (DECL_MAIN_P (decl1))
     /* main must return int.  grokfndecl should have corrected it
@@ -16436,12 +16440,6 @@ grokmethod (cp_decl_specifier_seq *declspecs,
   if (fndecl == error_mark_node)
     return error_mark_node;
 
-  if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
-    {
-      error ("invalid member function declaration");
-      return error_mark_node;
-    }
-
   if (attrlist)
     cplus_decl_attributes (&fndecl, attrlist, 0);
 
Index: testsuite/g++.dg/parse/typedef9.C
===================================================================
--- testsuite/g++.dg/parse/typedef9.C   (revision 274218)
+++ testsuite/g++.dg/parse/typedef9.C   (working copy)
@@ -1,8 +1,8 @@
 // PR c++/38794
 // { dg-do compile }
 
-typedef void foo () {} // { dg-error "invalid function declaration" }
+typedef void foo () {} // { dg-error "14:typedef may not be a function 
definition" }
 struct S
 {
-  typedef int bar (void) { return 0; } // { dg-error "invalid member function 
declaration" }
+  typedef int bar (void) { return 0; } // { dg-error "15:typedef may not be a 
member function definition" }
 };

Reply via email to