Re: [C++ PATCH] Fix up parsing of attribute-argument-clause of unknown attributes (PR c++/92648)

2019-11-26 Thread Jason Merrill

On 11/25/19 6:41 PM, Jakub Jelinek wrote:

Hi!

The standard says that argument-attribute-clause is:
attribute-argument-clause:
( balanced-token-seq[opt] )
balanced-token-seq:
balanced-token
balanced-token-seq balanced-token
balanced-token:
( balanced-token-seq[opt] )
[ balanced-token-seq[opt] ]
{ balanced-token-seq[opt] }
any token other than a parenthesis, a bracket, or a brace
but the C++ FE parses the attribute arguments always as an expression list
with the exception of identifier kept as is in certain cases.
That is just fine for all attributes we support right now, but what
arguments can have attributes of other compilers or not yet invented
attributes and how they should be parsed is unknown, so the only option is
IMHO to skip the balanced token set.  That is also what the C FE does and
what e.g. clang++ seems to do.

I'm not using cp_parser_skip_to_closing_parenthesis in the patch, because
cp_parser_skip_to_closing_parenthesis_1 has code to handle ?: specially and
I believe given the current grammar and that the argument doesn't have to be
necessarily an expression it is wrong, e.g.
[[whatever::whatever_else(???)]] could in theory be valid.

The primary reason for this change is that OpenMP 5.1 is likely going to
have some form of [[omp::... (arguments)]] attributes and the arguments
being considered there would be rejected by the current parser.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?


OK.


2019-11-26  Jakub Jelinek  

PR c++/92648
* parser.c (cp_parser_std_attribute): For unknown attributes,
skip balanced token seq instead of trying to parse
attribute-argument-clause as expression list.  Formatting fix.

* g++.dg/cpp0x/gen-attrs-71.C: New test.

--- gcc/cp/parser.c.jj  2019-11-22 09:33:08.899909913 +0100
+++ gcc/cp/parser.c 2019-11-25 18:29:06.230699448 +0100
@@ -26629,6 +26629,15 @@ cp_parser_std_attribute (cp_parser *pars
/* A GNU attribute that takes an identifier in parameter.  */
attr_flag = id_attr;
  
+if (as == NULL)

+  {
+   /* For unknown attributes, just skip balanced tokens instead of
+  trying to parse the arguments.  */
+   for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
+ cp_lexer_consume_token (parser->lexer);
+   return attribute;
+  }
+
  vec = cp_parser_parenthesized_expression_list
(parser, attr_flag, /*cast_p=*/false,
 /*allow_expansion_p=*/true,
@@ -26637,7 +26646,7 @@ cp_parser_std_attribute (cp_parser *pars
arguments = error_mark_node;
  else
{
-   if (vec->is_empty())
+   if (vec->is_empty ())
  /* e.g. [[attr()]].  */
  error_at (token->location, "parentheses must be omitted if "
"%qE attribute argument list is empty",
--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-71.C.jj2019-11-25 
18:22:09.486082583 +0100
+++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-71.C   2019-11-25 18:31:14.695730765 
+0100
@@ -0,0 +1,7 @@
+// PR c++/92648
+// { dg-do compile { target c++11 } }
+
+int a [[gnu::no_such_attribute(![!(!)!]!,;;)]];// { dg-warning 
"ignored" }
+int b [[no_such_namespace::nonexisting_attribute(linear(c, d : 2), reduction(*:e), 
linear(uval (f)))]];// { dg-warning "ignored" }
+int c [[gnu::nonexisting_attribute()]];// { dg-warning "ignored" }
+int d [[gnu::another_nonexistent_attr(1,"abcd",g+6)]];   // { dg-warning 
"ignored" }

Jakub





[C++ PATCH] Fix up parsing of attribute-argument-clause of unknown attributes (PR c++/92648)

2019-11-25 Thread Jakub Jelinek
Hi!

The standard says that argument-attribute-clause is:
attribute-argument-clause:
( balanced-token-seq[opt] )
balanced-token-seq:
balanced-token
balanced-token-seq balanced-token
balanced-token:
( balanced-token-seq[opt] )
[ balanced-token-seq[opt] ]
{ balanced-token-seq[opt] }
any token other than a parenthesis, a bracket, or a brace
but the C++ FE parses the attribute arguments always as an expression list
with the exception of identifier kept as is in certain cases.
That is just fine for all attributes we support right now, but what
arguments can have attributes of other compilers or not yet invented
attributes and how they should be parsed is unknown, so the only option is
IMHO to skip the balanced token set.  That is also what the C FE does and
what e.g. clang++ seems to do.

I'm not using cp_parser_skip_to_closing_parenthesis in the patch, because
cp_parser_skip_to_closing_parenthesis_1 has code to handle ?: specially and
I believe given the current grammar and that the argument doesn't have to be
necessarily an expression it is wrong, e.g.
[[whatever::whatever_else(???)]] could in theory be valid.

The primary reason for this change is that OpenMP 5.1 is likely going to
have some form of [[omp::... (arguments)]] attributes and the arguments
being considered there would be rejected by the current parser.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-11-26  Jakub Jelinek  

PR c++/92648
* parser.c (cp_parser_std_attribute): For unknown attributes,
skip balanced token seq instead of trying to parse
attribute-argument-clause as expression list.  Formatting fix.

* g++.dg/cpp0x/gen-attrs-71.C: New test.

--- gcc/cp/parser.c.jj  2019-11-22 09:33:08.899909913 +0100
+++ gcc/cp/parser.c 2019-11-25 18:29:06.230699448 +0100
@@ -26629,6 +26629,15 @@ cp_parser_std_attribute (cp_parser *pars
   /* A GNU attribute that takes an identifier in parameter.  */
   attr_flag = id_attr;
 
+if (as == NULL)
+  {
+   /* For unknown attributes, just skip balanced tokens instead of
+  trying to parse the arguments.  */
+   for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
+ cp_lexer_consume_token (parser->lexer);
+   return attribute;
+  }
+
 vec = cp_parser_parenthesized_expression_list
   (parser, attr_flag, /*cast_p=*/false,
/*allow_expansion_p=*/true,
@@ -26637,7 +26646,7 @@ cp_parser_std_attribute (cp_parser *pars
   arguments = error_mark_node;
 else
   {
-   if (vec->is_empty())
+   if (vec->is_empty ())
  /* e.g. [[attr()]].  */
  error_at (token->location, "parentheses must be omitted if "
"%qE attribute argument list is empty",
--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-71.C.jj2019-11-25 
18:22:09.486082583 +0100
+++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-71.C   2019-11-25 18:31:14.695730765 
+0100
@@ -0,0 +1,7 @@
+// PR c++/92648
+// { dg-do compile { target c++11 } }
+
+int a [[gnu::no_such_attribute(![!(!)!]!,;;)]];// { dg-warning 
"ignored" }
+int b [[no_such_namespace::nonexisting_attribute(linear(c, d : 2), 
reduction(*:e), linear(uval (f)))]];// { dg-warning "ignored" }
+int c [[gnu::nonexisting_attribute()]];// { dg-warning "ignored" }
+int d [[gnu::another_nonexistent_attr(1,"abcd",g+6)]]; // { dg-warning 
"ignored" }

Jakub