https://gcc.gnu.org/g:87492fb3fd5e7510983e0275a38ba95769335018

commit r15-5734-g87492fb3fd5e7510983e0275a38ba95769335018
Author: Joseph Myers <josmy...@redhat.com>
Date:   Wed Nov 27 22:27:08 2024 +0000

    c: Fix ICE using function name in parameter type in old-style function 
definition [PR91193]
    
    As reported in bug 91193, if an old-style function definition
    redeclares a typedef name as a function, then uses that function name
    at the start of the first old-style parameter definition, then the
    parser interprets that token as a typedef name (because lookahead
    occurred before processing of the function declarator completed), but
    when it is looked up in processing that parameter definition, what is
    found is the redefinition, resulting in an ICE.
    
    The function name's scope starts at the end of its declarator, so this
    is similar to other cases where we call
    c_parser_maybe_reclassify_token because lookahead might have
    classified a token as being a typedef or not based on information from
    the wrong scope; do so in this case as well, so resulting in the
    expected parse errors from using something that's no longer a typedef
    name as if it were a typedef name, and eliminating the ICE.
    
    Bootstrapped with no regressions for x86_64-pc-linux-gnu.
    
            PR c/91193
    
    gcc/c/
            * c-parser.cc (c_parser_maybe_reclassify_token): Define earlier.
            (c_parser_declaration_or_fndef): Call
            c_parser_maybe_reclassify_token before parsing old-style parameter
            definitions.
    
    gcc/testsuite/
            * gcc.dg/pr91193-1.c, gcc.dg/pr91193-2.c: New tests.

Diff:
---
 gcc/c/c-parser.cc                | 75 ++++++++++++++++++++--------------------
 gcc/testsuite/gcc.dg/pr91193-1.c | 12 +++++++
 gcc/testsuite/gcc.dg/pr91193-2.c | 12 +++++++
 3 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0e6f87ed5a29..6eaea2cf1ca7 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -2129,6 +2129,43 @@ handle_assume_attribute (location_t here, tree attrs, 
bool nested)
   return remove_attribute ("gnu", "assume", attrs);
 }
 
+/* We might need to reclassify any previously-lexed identifier, e.g.
+   when we've left a for loop with an if-statement without else in the
+   body - we might have used a wrong scope for the token.  See PR67784.  */
+
+static void
+c_parser_maybe_reclassify_token (c_parser *parser)
+{
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      c_token *token = c_parser_peek_token (parser);
+
+      if (token->id_kind != C_ID_CLASSNAME)
+       {
+         tree decl = lookup_name (token->value);
+
+         token->id_kind = C_ID_ID;
+         if (decl)
+           {
+             if (TREE_CODE (decl) == TYPE_DECL)
+               token->id_kind = C_ID_TYPENAME;
+           }
+         else if (c_dialect_objc ())
+           {
+             tree objc_interface_decl = objc_is_class_name (token->value);
+             /* Objective-C class names are in the same namespace as
+                variables and typedefs, and hence are shadowed by local
+                declarations.  */
+             if (objc_interface_decl)
+               {
+                 token->value = objc_interface_decl;
+                 token->id_kind = C_ID_CLASSNAME;
+               }
+           }
+       }
+    }
+}
+
 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
    6.7, 6.9.1, C11 6.7, 6.9.1).  If FNDEF_OK is true, a function definition
    is accepted; otherwise (old-style parameter declarations) only other
@@ -3021,6 +3058,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool 
fndef_ok,
         function definitions either.  */
       int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
       debug_nonbind_markers_p = 0;
+      c_parser_maybe_reclassify_token (parser);
       while (c_parser_next_token_is_not (parser, CPP_EOF)
             && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
        c_parser_declaration_or_fndef (parser, false, false, false,
@@ -8359,43 +8397,6 @@ c_parser_else_body (c_parser *parser, const 
token_indent_info &else_tinfo,
   return c_end_compound_stmt (body_loc, block, flag_isoc99);
 }
 
-/* We might need to reclassify any previously-lexed identifier, e.g.
-   when we've left a for loop with an if-statement without else in the
-   body - we might have used a wrong scope for the token.  See PR67784.  */
-
-static void
-c_parser_maybe_reclassify_token (c_parser *parser)
-{
-  if (c_parser_next_token_is (parser, CPP_NAME))
-    {
-      c_token *token = c_parser_peek_token (parser);
-
-      if (token->id_kind != C_ID_CLASSNAME)
-       {
-         tree decl = lookup_name (token->value);
-
-         token->id_kind = C_ID_ID;
-         if (decl)
-           {
-             if (TREE_CODE (decl) == TYPE_DECL)
-               token->id_kind = C_ID_TYPENAME;
-           }
-         else if (c_dialect_objc ())
-           {
-             tree objc_interface_decl = objc_is_class_name (token->value);
-             /* Objective-C class names are in the same namespace as
-                variables and typedefs, and hence are shadowed by local
-                declarations.  */
-             if (objc_interface_decl)
-               {
-                 token->value = objc_interface_decl;
-                 token->id_kind = C_ID_CLASSNAME;
-               }
-           }
-       }
-    }
-}
-
 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
 
    if-statement:
diff --git a/gcc/testsuite/gcc.dg/pr91193-1.c b/gcc/testsuite/gcc.dg/pr91193-1.c
new file mode 100644
index 000000000000..52999a7edd3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91193-1.c
@@ -0,0 +1,12 @@
+/* Test ICE using function name in parameter type in old-style function
+   definition (bug 91193).  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu17" } */
+
+typedef int T;
+
+void
+T (x) /* { dg-error "redeclared as different kind of symbol|defaults to 'int'" 
} */
+     T x; /* { dg-error "expected declaration specifiers" } */
+{
+}
diff --git a/gcc/testsuite/gcc.dg/pr91193-2.c b/gcc/testsuite/gcc.dg/pr91193-2.c
new file mode 100644
index 000000000000..7ca0e728eba6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91193-2.c
@@ -0,0 +1,12 @@
+/* Test ICE using function name in parameter type in old-style function
+   definition (bug 91193).  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu17" } */
+
+typedef int T;
+
+void
+f (void)
+{
+  void T (x) T x; { } /* { dg-error "expected declaration specifiers|defaults 
to 'int'" } */
+}

Reply via email to