[PATCH 1/2] Error out for Cilk_spawn or array expression in forbidden places

2014-10-03 Thread Andi Kleen
From: Andi Kleen a...@linux.intel.com

_Cilk_spawn or Cilk array expressions are only allowed on their own,
but not in for(), if(), switch, do, while, goto, etc.
The C parser didn't always check for that, which lead to ICEs earlier
for invalid code.

Add a generic helper that checks this and call it where needed
in the C frontend.

I chose to allow spawn/array for for init and increment expressions.
While the Cilk spec could be interpreted to forbid it there too
there didn't seem any reason to not allow it.

One dark corner is spawn, array in statement expressions not at
the end. Right now that's forbidden too.

gcc/c-family/:

2014-09-30  Andi Kleen  a...@linux.intel.com

PR c/60804
* c-common.h (check_no_cilk): Declare.
* cilk.c (get_error_location): New function.
(check_no_cilk): Dito.

gcc/c/:

2014-09-30  Andi Kleen  a...@linux.intel.com

PR c/60804
* c-parser.c (c_parser_statement_after_labels): Call
check_no_cilk.
(c_parser_if_statement): Dito.
(c_parser_switch_statement): Dito.
(c_parser_while_statement): Dito.
(c_parser_do_statement): Dito.
(c_parser_for_statement): Dito.
* c-typeck.c (c_finish_loop): Dito.
---
 gcc/c-family/c-common.h |  2 ++
 gcc/c-family/cilk.c | 39 
 gcc/c/c-parser.c| 67 -
 gcc/c/c-typeck.c|  8 ++
 4 files changed, 82 insertions(+), 34 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1e3477f..bd47860 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1395,4 +1395,6 @@ extern tree cilk_install_body_pedigree_operations (tree);
 extern void cilk_outline (tree, tree *, void *);
 extern bool contains_cilk_spawn_stmt (tree);
 extern tree cilk_for_number_of_iterations (tree);
+extern bool check_no_cilk (tree, const char *, const char *,
+  location_t loc = UNKNOWN_LOCATION);
 #endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 5b6684a..d7f1bb7 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -1312,3 +1312,42 @@ contains_cilk_spawn_stmt (tree expr)
   return walk_tree (expr, contains_cilk_spawn_stmt_walker, NULL, NULL)
 != NULL_TREE;
 }
+
+/* Return a error location for EXPR if LOC is not set.  */
+
+static location_t
+get_error_location (tree expr, location_t loc)
+{
+  if (loc == UNKNOWN_LOCATION)
+{
+  if (TREE_CODE (expr) == MODIFY_EXPR)
+expr = TREE_OPERAND (expr, 0);
+  loc = EXPR_LOCATION (expr);
+}
+  return loc;
+}
+
+/* Check that no array notation or spawn statement is in EXPR.
+   If not true generate an error at LOC for ARRAY_GMSGID or
+   SPAWN_MSGID.  */
+
+bool
+check_no_cilk (tree expr, const char *array_msgid, const char *spawn_msgid,
+ location_t loc)
+{
+  if (!flag_cilkplus)
+return false;
+  if (contains_array_notation_expr (expr))
+{
+  loc = get_error_location (expr, loc);
+  error_at (loc, array_msgid);
+  return true;
+}
+  if (walk_tree (expr, contains_cilk_spawn_stmt_walker, NULL, NULL))
+{
+  loc = get_error_location (expr, loc);
+  error_at (loc, spawn_msgid);
+  return true;
+}
+  return false;
+}
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 0d159fd..6c45d6a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -4926,6 +4926,11 @@ c_parser_statement_after_labels (c_parser *parser)
 
  c_parser_consume_token (parser);
  val = c_parser_expression (parser);
+ if (check_no_cilk (val.value,
+Cilk array notation cannot be used as a 
computed goto expression,
+%_Cilk_spawn% statement cannot be used as a 
computed goto expression,
+loc))
+   val.value = error_mark_node;
  val = convert_lvalue_to_rvalue (loc, val, false, true);
  stmt = c_finish_goto_ptr (loc, val.value);
}
@@ -4979,8 +4984,15 @@ c_parser_statement_after_labels (c_parser *parser)
{
  struct c_expr expr = c_parser_expression (parser);
  expr = convert_lvalue_to_rvalue (loc, expr, false, false);
- expr.value = c_fully_fold (expr.value, false, NULL);
- stmt = objc_build_throw_stmt (loc, expr.value);
+ if (check_no_cilk (expr.value,
+Cilk array notation cannot be used for a throw expression,
+%_Cilk_spawn% statement cannot be used for a throw 
expression))
+   expr.value = error_mark_node;
+ else
+   {
+ expr.value = c_fully_fold (expr.value, false, NULL);
+ stmt = objc_build_throw_stmt (loc, expr.value);
+   }
  goto expect_semicolon;
}
  break;
@@ -5163,6 +5175,11 @@ 

Re: [PATCH 1/2] Error out for Cilk_spawn or array expression in forbidden places

2014-10-03 Thread Jeff Law

On 10/03/14 08:08, Andi Kleen wrote:

From: Andi Kleen a...@linux.intel.com

_Cilk_spawn or Cilk array expressions are only allowed on their own,
but not in for(), if(), switch, do, while, goto, etc.
The C parser didn't always check for that, which lead to ICEs earlier
for invalid code.

Add a generic helper that checks this and call it where needed
in the C frontend.

I chose to allow spawn/array for for init and increment expressions.
While the Cilk spec could be interpreted to forbid it there too
there didn't seem any reason to not allow it.

One dark corner is spawn, array in statement expressions not at
the end. Right now that's forbidden too.

gcc/c-family/:

2014-09-30  Andi Kleen  a...@linux.intel.com

PR c/60804
* c-common.h (check_no_cilk): Declare.
* cilk.c (get_error_location): New function.
(check_no_cilk): Dito.

gcc/c/:

2014-09-30  Andi Kleen  a...@linux.intel.com

PR c/60804
* c-parser.c (c_parser_statement_after_labels): Call
check_no_cilk.
(c_parser_if_statement): Dito.
(c_parser_switch_statement): Dito.
(c_parser_while_statement): Dito.
(c_parser_do_statement): Dito.
(c_parser_for_statement): Dito.
* c-typeck.c (c_finish_loop): Dito.

OK.
Jeff



Re: [PATCH 1/2] Error out for Cilk_spawn or array expression in forbidden places

2014-10-03 Thread Bernhard Reutner-Fischer
On 3 October 2014 16:08:57 CEST, Andi Kleen a...@firstfloor.org wrote:
From: Andi Kleen a...@linux.intel.com

   (check_no_cilk): Dito.

I'm just curious, but isn't the english term ditto (im österreichischen ugs. 
detto, think latin idem) ?