Hi!

The r253411 change to improve diagnostics added code to set DECL_ARGUMENTS
to the declarator->u.arg_info->parms.  My understanding is that this was
meant for function prototypes, so that we can emit better diagnostics for
those.  Unfortunately, start_decl doesn't always return a new decl, but
returns what pushdecl returned, which could be the new prototype, but could
be some earlier prototyped or defined function.  The expansion etc. is very
unhappy if a function definition changes in the middle from having no
arguments into one with DECL_ARGUMENTs, especially if those arguments are
invalid.  So, this patch limits that change to prototypes only, doesn't try
to modify a function definition.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-02-05  Jakub Jelinek  <ja...@redhat.com>

        PR c/89211
        * c-parser.c (c_parser_declaration_or_fndef): Don't update
        DECL_ARGUMENTS of d if it has been defined already.  Use a single if
        instead of 3 nested ifs.

        * gcc.dg/pr89211.c: New test.

--- gcc/c/c-parser.c.jj 2019-01-09 19:55:01.071371422 +0100
+++ gcc/c/c-parser.c    2019-02-05 20:57:14.460652556 +0100
@@ -2154,10 +2154,12 @@ c_parser_declaration_or_fndef (c_parser
              tree d = start_decl (declarator, specs, false,
                                   chainon (postfix_attrs,
                                            all_prefix_attrs));
-             if (d && TREE_CODE (d) == FUNCTION_DECL)
-               if (declarator->kind == cdk_function)
-                 if (DECL_ARGUMENTS (d) == NULL_TREE)
-                   DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
+             if (d
+                 && TREE_CODE (d) == FUNCTION_DECL
+                 && declarator->kind == cdk_function
+                 && DECL_ARGUMENTS (d) == NULL_TREE
+                 && DECL_INITIAL (d) == NULL_TREE)
+               DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
              if (omp_declare_simd_clauses.exists ())
                {
                  tree parms = NULL_TREE;
--- gcc/testsuite/gcc.dg/pr89211.c.jj   2019-02-05 20:59:45.113159822 +0100
+++ gcc/testsuite/gcc.dg/pr89211.c      2019-02-05 20:59:40.331238946 +0100
@@ -0,0 +1,8 @@
+/* PR c/89211 */
+/* { dg-do compile } */
+
+void foo ();
+void foo ()
+{
+  void foo (struct S); /* { dg-warning "declared inside parameter list" } */
+}

        Jakub

Reply via email to