On Fri, May 18, 2018 at 10:30 AM, Paolo Carlini <paolo.carl...@oracle.com> wrote: > Hi, > > On 18/05/2018 16:19, Jason Merrill wrote: >> >> On Fri, May 18, 2018 at 10:05 AM, Paolo Carlini >> <paolo.carl...@oracle.com> wrote: >>> >>> Hi, >>> >>> On 18/05/2018 15:56, Jason Merrill wrote: >>>> >>>> I had in mind moving the call to cp_parser_check_condition_declarator >>>> into the block controlled by cp_parser_parse_definitely; this is a >>>> semantic check that should follow the syntactic checks. If there's no >>>> initializer, it doesn't parse as a condition declaration, so we don't >>>> want to complain about it being a semantically invalid condition >>>> declaration. >>> >>> If we do that we are back to something very, very, similar to what I >>> posted >>> at the beginning of the thread, right? Therefore, for all the testcases >>> which don't have an initializer we end-up with *horrible*, literally >>> *horrible* cascades of errors, plus we ICE on the c++/84588 variants >>> without >>> an initializer. >> >> Ah. Why is that? >> >> I guess it's desirable to also give this error when the declarator is >> followed by ) or ; rather than other tokens that could be more >> expression (like in A(a).x in the comment). > > I can certainly try to implement this, maybe just something minimal to begin > with, as you say ) or ; alone would be safe and would already take care of > all the tests I have around. > > Certainly, unconditionally deferring at that point to cp_parser_expression > leads to *very* bad error-recovery. For fun, try with 8.1.0: > > void foo() > { > for (;void bar();); > } > > and it gets worse.
It would also need to be only for a non-parenthesized declarator, which can't be an expression; a parenthesized declarator can be, as in this well-formed testcase: bool (bar()) { return 0; } // declaration void foo() { for (;bool (bar());); // expression } Jason