diff options
author | Mark Wielaard <mark@klomp.org> | 2020-05-24 18:01:51 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2020-06-04 01:15:56 +0200 |
commit | 34e4962aed08b38f37e37242234bfbbd1b897f39 (patch) | |
tree | 6f9f484668d6f544d2b830ee652f18c5ffe77b72 | |
parent | 29e304fd5f9097335c5d7d1b16f139439eeabe1f (diff) | |
download | gcc-34e4962aed08b38f37e37242234bfbbd1b897f39.zip gcc-34e4962aed08b38f37e37242234bfbbd1b897f39.tar.gz gcc-34e4962aed08b38f37e37242234bfbbd1b897f39.tar.bz2 |
diagnostics: Add function call parens matching to c_parser.
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.
-rw-r--r-- | gcc/c/c-parser.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/missing-close-func-paren.c | 40 |
2 files changed, 57 insertions, 15 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 5d11e7e..23d6fa2 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 0000000..3177e25 --- /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 "" } */ +} |