This patch fixes ICE when statement expression used in old-style function declaration parameter list. See

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30552

In c_parser_postfix_expression (), after seeing a left paren followed by a left curly brace, in addition to checking for existing statement list, also check to see if we're in the parameter scope an old-style function declaration. In either case, generate a "braced-group within expression allowed only inside a function" error.

Patch successfully bootstrapped and tested on x86_64-linux.

--Dave

/c
2018-03-13  David Pagan  <dave.pa...@oracle.com>

        PR c/30552
        * c-decl.c (old_style_parameter_scope): New function.
        * c-parser.c (c_parser_postfix_expression): Check for statement
        expressions in old-style function parameter list declarations.

/c-family
2018-03-13  David Pagan  <dave.pa...@oracle.com>

        PR c/30552
        * c-common.h (old_style_parameter_scope): New extern declaration.

/testsuite
2018-03-13  David Pagan  <dave.pa...@oracle.com>

        PR c/30552
        * gcc.dg/noncompile/pr30552-1.c: New test.
        * gcc.dg/noncompile/pr30552-2.c: New test.
        * gcc.dg/noncompile/pr30552-3.c: New test.
        * gcc.dg/noncompile/pr30552-4.c: New test.
Index: c/c-decl.c
===================================================================
--- c/c-decl.c  (revision 258257)
+++ c/c-decl.c  (working copy)
@@ -952,6 +952,17 @@ global_bindings_p (void)
   return current_scope == file_scope;
 }
 
+/* Return true if we're declaring parameters in an old-style function
+   declaration.  */
+
+bool
+old_style_parameter_scope (void)
+{
+  /* If processing parameters and there is no function statement list, we
+   * have an old-style function declaration.  */
+  return (current_scope->parm_flag && !DECL_SAVED_TREE(current_function_decl));
+}
+
 void
 keep_next_level (void)
 {
Index: c/c-parser.c
===================================================================
--- c/c-parser.c        (revision 258257)
+++ c/c-parser.c        (working copy)
@@ -7929,7 +7929,10 @@ c_parser_postfix_expression (c_parser *parser)
          c_parser_consume_token (parser);
          brace_loc = c_parser_peek_token (parser)->location;
          c_parser_consume_token (parser);
-         if (!building_stmt_list_p ())
+         /* If we've not yet started the current function's statement list, 
+            or we're in the parameter scope of an old-style function
+            declaration, statement expressions are not allowed.  */
+         if (!building_stmt_list_p () || old_style_parameter_scope ())
            {
              error_at (loc, "braced-group within expression allowed "
                        "only inside a function");
Index: c-family/c-common.h
===================================================================
--- c-family/c-common.h (revision 258257)
+++ c-family/c-common.h (working copy)
@@ -581,6 +581,7 @@ extern tree push_stmt_list (void);
 extern tree pop_stmt_list (tree);
 extern tree add_stmt (tree);
 extern void push_cleanup (tree, tree, bool);
+extern bool old_style_parameter_scope (void);
 
 extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
                               location_t, tree, tree);
Index: testsuite/gcc.dg/noncompile/pr30552-1.c
===================================================================
--- testsuite/gcc.dg/noncompile/pr30552-1.c     (revision 0)
+++ testsuite/gcc.dg/noncompile/pr30552-1.c     (working copy)
@@ -0,0 +1,17 @@
+/* PR c/30552 */
+
+/* Statement expression as formal array argument size in nested old-style 
+   function declaration should generate user error, not internal compiler 
+   error.  */
+
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int main()
+{
+  void fun(int a) /* { dg-error "old-style parameter declarations in 
prototyped function definition" } */
+    int a[({void h(){}2;})]; /* { dg-error "braced-group within expression 
allowed only inside a function" } */
+  {
+  }
+  return 0;
+}
Index: testsuite/gcc.dg/noncompile/pr30552-2.c
===================================================================
--- testsuite/gcc.dg/noncompile/pr30552-2.c     (revision 0)
+++ testsuite/gcc.dg/noncompile/pr30552-2.c     (working copy)
@@ -0,0 +1,17 @@
+/* PR c/30552 */
+
+/* Another example of a statement expression as formal array argument size in
+ * nested old-style function declaration should generate user error, not 
+ * internal compiler error.  */
+
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int main()
+{
+  void fun(a)
+    int a[({int b=2; b;})]; /* { dg-error "braced-group within expression 
allowed only inside a function" } */
+  {
+  }
+  return 0;
+}
Index: testsuite/gcc.dg/noncompile/pr30552-3.c
===================================================================
--- testsuite/gcc.dg/noncompile/pr30552-3.c     (revision 0)
+++ testsuite/gcc.dg/noncompile/pr30552-3.c     (working copy)
@@ -0,0 +1,15 @@
+/* PR c/30552 */
+
+/* Related example where statement expression used as old-style formal array 
+ * argument size in an invalid nested function declaration should generate 
+ * user error, not internal compiler error. */
+
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int main()
+{
+  int g()
+    int a[( {int b} )]; /* { dg-error "braced-group within expression allowed 
only inside a function|declaration for parameter" } */
+  return 0; /* { dg-error "expected declaration specifiers before" } */
+} /* { dg-error "expected declaration specifiers before|end of input|expected 
declaration or statement at end of input" } */
Index: testsuite/gcc.dg/noncompile/pr30552-4.c
===================================================================
--- testsuite/gcc.dg/noncompile/pr30552-4.c     (revision 0)
+++ testsuite/gcc.dg/noncompile/pr30552-4.c     (working copy)
@@ -0,0 +1,15 @@
+/* PR c/30552 */
+
+/* Statement expression as formal array argument size in nested function
+ * prototype scope is valid.  */
+
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int main()
+{
+  void fun(int a[({void h(){}10;})])
+  {
+  }
+  return 0;
+}

Reply via email to