diagnostics: Add function call parens matching to c_parser.

Message ID 20200524214634.65346-1-mark@klomp.org
State New
Headers show
Series
  • diagnostics: Add function call parens matching to c_parser.
Related show

Commit Message

Mark Wielaard May 24, 2020, 9:46 p.m.
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.
---
 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

-- 
2.20.1

Comments

Mark Wielaard May 31, 2020, 9:33 p.m. | #1
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

>
Joseph Myers June 3, 2020, 11:13 p.m. | #2
On Sun, 31 May 2020, Mark Wielaard wrote:

> 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.


OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

Patch

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 "" } */
+}