From f7584c811623675be258da5195d8e8daeb562975 Mon Sep 17 00:00:00 2001 From: David Pagan Date: Wed, 2 May 2018 17:22:26 +0000 Subject: [PATCH] re PR c/30552 (gcc crashes when compiling examples with GNU statement expressions in VLAs (also involved: nested functions declared K&R-style)) 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-parser.h (old_style_parameter_scope): New extern declaration. 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. From-SVN: r259849 --- gcc/c/ChangeLog | 8 ++++++++ gcc/c/c-decl.c | 11 +++++++++++ gcc/c/c-parser.c | 5 ++++- gcc/c/c-parser.h | 3 +++ gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/gcc.dg/noncompile/pr30552-1.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/noncompile/pr30552-2.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/noncompile/pr30552-3.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/noncompile/pr30552-4.c | 15 +++++++++++++++ 9 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/noncompile/pr30552-1.c create mode 100644 gcc/testsuite/gcc.dg/noncompile/pr30552-2.c create mode 100644 gcc/testsuite/gcc.dg/noncompile/pr30552-3.c create mode 100644 gcc/testsuite/gcc.dg/noncompile/pr30552-4.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7a3cf3f93eb..d88d70d99fc 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2018-05-02 David Pagan + + 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-parser.h (old_style_parameter_scope): New extern declaration. + 2018-04-25 Jakub Jelinek PR sanitizer/84307 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 7255588ac1e..3c4b18edf56 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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) { diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 47720861d3f..6b41a615dbd 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7930,7 +7930,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"); diff --git a/gcc/c/c-parser.h b/gcc/c/c-parser.h index da77f68eb1c..c9d38ace96c 100644 --- a/gcc/c/c-parser.h +++ b/gcc/c/c-parser.h @@ -155,6 +155,9 @@ extern c_token * c_parser_tokens_buf (c_parser *parser, unsigned n); extern bool c_parser_error (c_parser *parser); extern void c_parser_set_error (c_parser *parser, bool); +/* A bit of a hack to have this here. It would be better in a c-decl.h. */ +extern bool old_style_parameter_scope (void); + /* Return true if the next token from PARSER has the indicated TYPE. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ecd2de3bc27..63750af3495 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-05-02 David Pagan + + 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. + 2018-05-02 Richard Biener PR tree-optimization/85597 diff --git a/gcc/testsuite/gcc.dg/noncompile/pr30552-1.c b/gcc/testsuite/gcc.dg/noncompile/pr30552-1.c new file mode 100644 index 00000000000..a19d9e08fe9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/noncompile/pr30552-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/noncompile/pr30552-2.c b/gcc/testsuite/gcc.dg/noncompile/pr30552-2.c new file mode 100644 index 00000000000..d88488397c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/noncompile/pr30552-2.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/noncompile/pr30552-3.c b/gcc/testsuite/gcc.dg/noncompile/pr30552-3.c new file mode 100644 index 00000000000..7b48e763ece --- /dev/null +++ b/gcc/testsuite/gcc.dg/noncompile/pr30552-3.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/noncompile/pr30552-4.c b/gcc/testsuite/gcc.dg/noncompile/pr30552-4.c new file mode 100644 index 00000000000..d1f9c6b083a --- /dev/null +++ b/gcc/testsuite/gcc.dg/noncompile/pr30552-4.c @@ -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; +} -- 2.30.2