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;
+}
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);
}
{
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;
block = c_begin_compound_stmt (flag_isoc99);
loc = c_parser_peek_token (parser)->location;
cond = c_parser_paren_condition (parser);
+ if (flag_cilkplus && contains_cilk_spawn_stmt (cond))
+ {
+ error_at (loc, "if statement cannot contain %<Cilk_spawn%>");
+ cond = error_mark_node;
+ }
in_if_block = parser->in_if_block;
parser->in_if_block = true;
first_body = c_parser_if_body (parser, &first_if);
ce = c_parser_expression (parser);
ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, false);
expr = ce.value;
- if (flag_cilkplus && contains_array_notation_expr (expr))
- {
- error_at (switch_cond_loc,
- "array notations cannot be used as a condition for switch "
- "statement");
- expr = error_mark_node;
- }
+ /* ??? expr has no valid location? */
+ if (check_no_cilk (expr,
+ "Cilk array notation cannot be used as a condition for switch statement",
+ "%<_Cilk_spawn%> statement cannot be used as a condition for switch statement",
+ switch_cond_loc))
+ expr = error_mark_node;
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
block = c_begin_compound_stmt (flag_isoc99);
loc = c_parser_peek_token (parser)->location;
cond = c_parser_paren_condition (parser);
- if (flag_cilkplus && contains_array_notation_expr (cond))
- {
- error_at (loc, "array notations cannot be used as a condition for while "
- "statement");
- cond = error_mark_node;
- }
-
+ if (check_no_cilk (cond,
+ "Cilk array notation cannot be used as a condition for while statement",
+ "%<_Cilk_spawn%> statement cannot be used as a condition for while statement"))
+ cond = error_mark_node;
if (ivdep && cond != error_mark_node)
cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
build_int_cst (integer_type_node,
new_cont = c_cont_label;
c_cont_label = save_cont;
cond = c_parser_paren_condition (parser);
- if (flag_cilkplus && contains_array_notation_expr (cond))
- {
- error_at (loc, "array notations cannot be used as a condition for a "
- "do-while statement");
- cond = error_mark_node;
- }
+ if (check_no_cilk (cond,
+ "Cilk array notation cannot be used as a condition for a do-while statement",
+ "%<_Cilk_spawn%> statement cannot be used as a condition for a do-while statement"))
+ cond = error_mark_node;
if (ivdep && cond != error_mark_node)
cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
build_int_cst (integer_type_node,
struct c_expr ce;
tree init_expression;
ce = c_parser_expression (parser);
+ /* In theory we could forbid _Cilk_spawn here, as the spec says "only in top
+ level statement", but it works just fine, so allow it. */
init_expression = ce.value;
parser->objc_could_be_foreach_context = false;
if (c_parser_next_token_is_keyword (parser, RID_IN))
else
{
cond = c_parser_condition (parser);
- if (flag_cilkplus && contains_array_notation_expr (cond))
- {
- error_at (loc, "array notations cannot be used in a "
- "condition for a for-loop");
- cond = error_mark_node;
- }
+ if (check_no_cilk (cond,
+ "Cilk array notation cannot be used in a condition for a for-loop",
+ "%<_Cilk_spawn%> statement cannot be used in a condition for a for-loop"))
+ cond = error_mark_node;
c_parser_skip_until_found (parser, CPP_SEMICOLON,
"expected %<;%>");
}