On Tue, Dec 05, 2023 at 08:51:51AM +0100, Jakub Jelinek wrote: > Hi! > > When working on the previous patch I put [[]] [[]] asm (""); into a > testcase, but was surprised it wasn't parsed.
By wasn't parsed you mean we gave an error, right? I only see an error with block-scope [[]] [[]];. > The problem is that when cp_parser_std_attribute_spec returns NULL, it > can mean 2 different things, one is that the next token(s) are neither > [[ nor alignas (in that case the caller should break from the loop), > or when we parsed something like [[]] - it was valid attribute specifier, > but didn't specify any attributes in it. > > The following patch fixes that by adding another parameter to differentiate > between the cases, guess another option would be to use some magic > tree value for the break case instead of NULL_TREE (but error_mark_node is > already taken and means something else). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > Or shall I go with some magic return which will never happen otherwise? > void_node? It seems marginally better to me to use void_list_node so that we don't need a new parm, like what we do when parsing parameters: ()/(void)/(...), but I should let others decide. If we stay with any_p, please add a comment saying that it means "found any", not "accepts any" or something else. Thanks, > 2023-12-05 Jakub Jelinek <ja...@redhat.com> > > * parser.cc (cp_parser_std_attribute_spec): Add ANY_P argument, set > what it points to initially to true and only if token is neither > CPP_OPEN_SQUARE nor RID_ALIGNAS CPP_KEYWORD set it to false. > (cp_parser_std_attribute_spec_seq): Adjust > cp_parser_std_attribute_spec caller. If it returns NULL_TREE and > any_p is true, continue rather than break. > > * g++.dg/cpp0x/gen-attrs-79.C: New test. > > --- gcc/cp/parser.cc.jj 2023-12-04 20:23:53.225009856 +0100 > +++ gcc/cp/parser.cc 2023-12-04 20:49:21.160426104 +0100 > @@ -2703,7 +2703,7 @@ static tree cp_parser_gnu_attribute_list > static tree cp_parser_std_attribute > (cp_parser *, tree); > static tree cp_parser_std_attribute_spec > - (cp_parser *); > + (cp_parser *, bool *); > static tree cp_parser_std_attribute_spec_seq > (cp_parser *); > static size_t cp_parser_skip_std_attribute_spec_seq > @@ -30265,11 +30265,12 @@ void cp_parser_late_contract_condition ( > conditional-expression ] ] */ > > static tree > -cp_parser_std_attribute_spec (cp_parser *parser) > +cp_parser_std_attribute_spec (cp_parser *parser, bool *any_p) > { > tree attributes = NULL_TREE; > cp_token *token = cp_lexer_peek_token (parser->lexer); > > + *any_p = true; > if (token->type == CPP_OPEN_SQUARE > && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE) > { > @@ -30342,7 +30343,10 @@ cp_parser_std_attribute_spec (cp_parser > > if (token->type != CPP_KEYWORD > || token->keyword != RID_ALIGNAS) > - return NULL_TREE; > + { > + *any_p = false; > + return NULL_TREE; > + } > > cp_lexer_consume_token (parser->lexer); > maybe_warn_cpp0x (CPP0X_ATTRIBUTES); > @@ -30414,9 +30418,16 @@ cp_parser_std_attribute_spec_seq (cp_par > > while (true) > { > - tree attr_spec = cp_parser_std_attribute_spec (parser); > + bool any_p; > + tree attr_spec = cp_parser_std_attribute_spec (parser, &any_p); > if (attr_spec == NULL_TREE) > - break; > + { > + /* Accept [[]][[]]; for which cp_parser_std_attribute_spec > + also returns NULL_TREE as there are no attributes. */ > + if (any_p) > + continue; > + break; > + } > if (attr_spec == error_mark_node) > return error_mark_node; > > --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C.jj 2023-12-04 > 20:38:35.122574430 +0100 > +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C 2023-12-04 20:38:29.468654143 > +0100 > @@ -0,0 +1,9 @@ > +// { dg-do compile { target c++11 } } > + > +[[]] [[]]; > + > +[[]] [[]] void > +foo () > +{ > + [[]] [[]]; > +} > > Jakub > Marek