This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C PATCH] Fix ICE on invalid Cilk+ code (PR c/69798)
- From: Marek Polacek <polacek at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Joseph Myers <joseph at codesourcery dot com>
- Date: Thu, 3 Mar 2016 17:15:35 +0100
- Subject: Re: [C PATCH] Fix ICE on invalid Cilk+ code (PR c/69798)
- Authentication-results: sourceware.org; auth=none
- References: <20160303141541 dot GD10006 at redhat dot com> <20160303142801 dot GH3017 at tucnak dot redhat dot com>
On Thu, Mar 03, 2016 at 03:28:01PM +0100, 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?
Alternatively this one works as well. I don't know if any verification of the
result should be done (in the second call, the first one is invalid anyway).
2016-03-03 Marek Polacek <polacek@redhat.com>
PR c/69798
* c-parser.c (c_parser_postfix_expression): Call
c_parser_cast_expression instead of c_parser_postfix_expression.
* gcc.dg/cilk-plus/pr69798-1.c: New test.
* gcc.dg/cilk-plus/pr69798-2.c: New test.
diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index bb508b7..ce00457 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -8024,8 +8024,8 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "-fcilkplus must be enabled to use "
"%<_Cilk_spawn%>");
- expr = c_parser_postfix_expression (parser);
- expr.value = error_mark_node;
+ expr = c_parser_cast_expression (parser, NULL);
+ expr.value = error_mark_node;
}
else if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
{
@@ -8038,7 +8038,7 @@ c_parser_postfix_expression (c_parser *parser)
}
else
{
- expr = c_parser_postfix_expression (parser);
+ expr = c_parser_cast_expression (parser, NULL);
expr.value = build_cilk_spawn (loc, expr.value);
}
break;
diff --git gcc/testsuite/gcc.dg/cilk-plus/pr69798-1.c gcc/testsuite/gcc.dg/cilk-plus/pr69798-1.c
index e69de29..1120193 100644
--- gcc/testsuite/gcc.dg/cilk-plus/pr69798-1.c
+++ gcc/testsuite/gcc.dg/cilk-plus/pr69798-1.c
@@ -0,0 +1,12 @@
+/* PR c/69798 */
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int
+main ()
+{
+ _Cilk_spawn (void); /* { dg-error "expected expression" } */
+ _Cilk_spawn (char []); /* { dg-error "expected expression" } */
+ _Cilk_spawn (int *); /* { dg-error "expected expression" } */
+ _Cilk_spawn ({}); /* { dg-error "only function calls can be spawned" } */
+}
diff --git gcc/testsuite/gcc.dg/cilk-plus/pr69798-2.c gcc/testsuite/gcc.dg/cilk-plus/pr69798-2.c
index e69de29..66bcdc8 100644
--- gcc/testsuite/gcc.dg/cilk-plus/pr69798-2.c
+++ gcc/testsuite/gcc.dg/cilk-plus/pr69798-2.c
@@ -0,0 +1,11 @@
+/* PR c/69798 */
+/* { dg-do compile } */
+
+int
+main ()
+{
+ _Cilk_spawn (void); /* { dg-error "expected expression" } */
+ _Cilk_spawn (char []); /* { dg-error "expected expression" } */
+ _Cilk_spawn (int *); /* { dg-error "expected expression" } */
+ _Cilk_spawn ({}); /* { dg-error "only function calls can be spawned" } */
+}
Marek