On Fri, May 18, 2018 at 8:27 PM, Paolo Carlini <paolo.carl...@oracle.com> wrote: > On 19/05/2018 01:40, Jason Merrill wrote: >> On Fri, May 18, 2018 at 1:40 PM, Paolo Carlini <paolo.carl...@oracle.com> >> wrote: >>> >>> Hi again, >>> >>> I'm playing with a wild, wild idea: would it make sense to try *first* an >>> expression? Because, a quickly hacked draft appears to handle very >>> elegantly >>> all the possible cases of "junk" after the declarator, eg: >>> >>> void foo() >>> { >>> if (void bar()JUNK); >>> } >>> >>> and the parenthesized case, etc, etc. Before trying to seriously work on >>> that I wanted to ask... >> >> We'd need to try parsing as a declaration whether or not parsing as an >> expression works, since any ambiguous cases are treated as >> declarations [stmt.ambig]. > > Yeah, that complicates the implementation of my idea. However, I'm thinking > that at least *in the specific case of cp_parse_condition* from the > computational complexity point of view probably we wouldn't regress much, > because declarations are rare anyway, thus in most of the cases we end up > doing both anyway. If we do expressions first and we save the result, then I > believe when we can handle the declarator as something which cannot be a > function or an array even if we don't see the initializer much more easily, > we easily have a better diagnostic for things like > > if (int x); > > (another case we currently handle pretty badly, we don't talk about the > missing initializer at all!), we cope elegantly with any junk following the > wrong function/array declaration, etc. See that attached, if you are > curious, which essentially passes the testsuite modulo a nit (*) which > doesn't have anything to do with [stmt.ambig] per se (which of course is > *not* correctly implemented in the wip). > > Can you give me your opinion about the more detailed idea, in particular > whether we already have good infrastructure to implement [stmt.ambig] in > this context, thus to keep the first parsing as an expression around, > possibly returning to it if the parsing as a declaration fails??
I would expect it to cause different diagnostic issues, from complaining about something not being a proper declaration when it's really an expression. I also wonder about warning problems (either missed or bogus) due to trying these in a different order. How about doing cp_parser_commit_to_tentative_parse if we see something that must be a declaration? cp_parser_simple_declaration has /* If we have seen at least one decl-specifier, and the next token is not a parenthesis, then we must be looking at a declaration. (After "int (" we might be looking at a functional cast.) */ if (decl_specifiers.any_specifiers_p && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN) && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE) && !cp_parser_error_occurred (parser)) cp_parser_commit_to_tentative_parse (parser); That seems useful here, as well. Maybe factored into a separate function. Jason