On Sun, May 24, 2020 at 11:46:34PM +0200, Mark Wielaard wrote: > The C++ parser already tracks function call parens matching, but the C > parser doesn't. This adds the same functionality to the C parser and adds > a testcase showing the C++ and C parser matching function call parens > in an error message. > > gcc/c/ChangeLog: > > * c-parser.c (c_parser_postfix_expression_after_primary): Add > scope with matching_parens after CPP_OPEN_PAREN. > > gcc/testsuite/ChangeLog: > > * c-c++-common/missing-close-func-paren.c: New test.
Ping. > --- > gcc/c/c-parser.c | 32 ++++++++------- > .../c-c++-common/missing-close-func-paren.c | 40 +++++++++++++++++++ > 2 files changed, 57 insertions(+), 15 deletions(-) > create mode 100644 gcc/testsuite/c-c++-common/missing-close-func-paren.c > > diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c > index 5d11e7e73c16..23d6fa22b685 100644 > --- a/gcc/c/c-parser.c > +++ b/gcc/c/c-parser.c > @@ -10458,21 +10458,23 @@ c_parser_postfix_expression_after_primary (c_parser > *parser, > break; > case CPP_OPEN_PAREN: > /* Function call. */ > - c_parser_consume_token (parser); > - for (i = 0; i < 3; i++) > - { > - sizeof_arg[i] = NULL_TREE; > - sizeof_arg_loc[i] = UNKNOWN_LOCATION; > - } > - literal_zero_mask = 0; > - if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) > - exprlist = NULL; > - else > - exprlist = c_parser_expr_list (parser, true, false, &origtypes, > - sizeof_arg_loc, sizeof_arg, > - &arg_loc, &literal_zero_mask); > - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, > - "expected %<)%>"); > + { > + matching_parens parens; > + parens.consume_open (parser); > + for (i = 0; i < 3; i++) > + { > + sizeof_arg[i] = NULL_TREE; > + sizeof_arg_loc[i] = UNKNOWN_LOCATION; > + } > + literal_zero_mask = 0; > + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) > + exprlist = NULL; > + else > + exprlist = c_parser_expr_list (parser, true, false, &origtypes, > + sizeof_arg_loc, sizeof_arg, > + &arg_loc, &literal_zero_mask); > + parens.skip_until_found_close (parser); > + } > orig_expr = expr; > mark_exp_read (expr.value); > if (warn_sizeof_pointer_memaccess) > diff --git a/gcc/testsuite/c-c++-common/missing-close-func-paren.c > b/gcc/testsuite/c-c++-common/missing-close-func-paren.c > new file mode 100644 > index 000000000000..3177e250e1c3 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/missing-close-func-paren.c > @@ -0,0 +1,40 @@ > +/* { dg-options "-fdiagnostics-show-caret" } */ > + > +/* Verify that the C/C++ frontends show the pertinent opening symbol when > + a closing symbol is missing for a function call. */ > + > +/* Verify that, when they are on the same line, that the opening symbol is > + shown as a secondary range within the main diagnostic. */ > + > +extern int __attribute__((const)) foo (int a, int b, int c); > + > +void single_func () > +{ > + int single = > + foo (1, (1 + 2), (1 + 2 + 3):); /* { dg-error "expected '\\)' before ':' > token" } */ > + /* { dg-begin-multiline-output "" } > + foo (1, (1 + 2), (1 + 2 + 3):); > + ~ ^ > + ) > + { dg-end-multiline-output "" } */ > +} > + > +/* Verify that, when they are on different lines, that the opening symbol is > + shown via a secondary diagnostic. */ > + > +void multi_func () > +{ > + int multi = > + foo (1, /* { dg-message "to match this '\\('" } */ > + (1 + 2), > + (1 + 2 + 3):); /* { dg-error "expected '\\)' before ':' token" } */ > + /* { dg-begin-multiline-output "" } > + (1 + 2 + 3):); > + ^ > + ) > + { dg-end-multiline-output "" } */ > + /* { dg-begin-multiline-output "" } > + foo (1, > + ^ > + { dg-end-multiline-output "" } */ > +} > -- > 2.20.1 >