On Thu, Mar 03, 2016 at 10:52:20PM -0700, Jeff Law wrote:
> On 03/03/2016 07:28 AM, Jakub Jelinek wrote:
> >On Thu, Mar 03, 2016 at 03:15:41PM +0100, Marek Polacek wrote:
> >>This is ICE on invalid Cilk+ code.  cilk_spawn expects a function call, so 
> >>e.g.
> >>_Cilk_spawn (void) is invalid.  The function call after the cilk_spawn 
> >>keyword
> >>is parsed using recursive call in c_parser_postfix_expression (case
> >>RID_CILK_SPAWN).  Now, c_parser_postfix_expression sees '(' followed by a
> >>typename, so it thinks we're inside a compound literal, which means it 
> >>expects
> >>'{', but that isn't there, so we crash on the assert in 
> >>c_parser_braced_init:
> >>gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
> >>But as the comment in c_parser_postfix_expression says, the code for parsing
> >>a compound literal here is likely dead.  I made an experiment and added
> >>gcc_unreachable () in that block, ran regtest, and there were no failures.
> >>Thus it should be safe to just remove the code, which also fixes this ICE; 
> >>with
> >>the patch we just give a proper error and don't crash anymore.
> >>
> >>Bootstrapped/regtested on x86_64-linux, ok for trunk?  I'm actually slightly
> >>nervous about the change, so maybe better table until gcc7?
> >
> >This reminds me of PR67495.  Perhaps the answer here is also during the
> >_Cilk* stuff parsing don't call c_parser_postfix_expression, but call
> >c_parser_cast_expression instead and then verify what it got?
> That sounds more sensible to me -- as long as there aren't unintended side
> effects of calling c_parser_cast_expression.

The difference is that c_parser_cast_expression can parse (type)...,
++..., --..., &..., +..., -..., *..., ~..., !..., &&...,
sizeof/alignof/__extension__/__real/__imag/__transaction_{atomic,relaxed}...
Perhaps even safer version would be:
    if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
        && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
      {
        ... error handling ...
      }
    else
      ... c_parser_postfix_expression (parser);
But, even c_parser_postfix_expression parses tons of expressions that
aren't allowed there, so I think it is overkill.  It needs to check
afterwards, and from what I can see that happens in cilk_set_spawn_marker.
Thus I think c_parser_cast_expression is safe, it parses perhaps more
unexpected expressions, but will reject them all anyway, because they aren't
CALL_EXPR after parsing.

        Jakub

Reply via email to