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 @@ c_parser_if_statement (c_parser *parser)
   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);
@@ -5209,13 +5226,12 @@ c_parser_switch_statement (c_parser *parser)
       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
@@ -5255,13 +5271,10 @@ c_parser_while_statement (c_parser *parser, bool ivdep)
   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,
@@ -5307,12 +5320,10 @@ c_parser_do_statement (c_parser *parser, bool ivdep)
   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,
@@ -5464,6 +5475,8 @@ c_parser_for_statement (c_parser *parser, bool ivdep)
 	    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))
@@ -5505,12 +5518,10 @@ c_parser_for_statement (c_parser *parser, bool ivdep)
 	  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 %<;%>");
 	    }
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index f69c28b..9df1b94 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9600,12 +9600,8 @@ c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
 {
   tree entry = NULL, exit = NULL, t;
 
-  if (flag_cilkplus && contains_array_notation_expr (cond))
-    {
-      error_at (start_locus, "array notation expression cannot be used in a "
-		"loop%'s condition");
-      return;
-    }
+  /* In theory could forbid cilk spawn for loop increment expression,
+     but it should work just fine.  */
   
   /* If the condition is zero don't generate a loop construct.  */
   if (cond && integer_zerop (cond))
