> -----Original Message-----
> From: Jason Merrill [mailto:ja...@redhat.com]
> Sent: Wednesday, November 27, 2013 8:24 PM
> To: Iyer, Balaji V; gcc-patches@gcc.gnu.org
> Cc: Jeff Law
> Subject: Re: _Cilk_spawn and _Cilk_sync for C++
> 
> On 11/27/2013 05:59 PM, Iyer, Balaji V wrote:
> > Well, if I use copy_tree_body_r for C and C++, in lambda functions, it
> asserts in varasm.c. The main reason I see that, the copy_tree_body_r walks
> into the closure and then maps the variables from the lambda function from
> the spawner to the helper function.
> 
> It walks into the initializer for the closure object, yes.  And gets confused 
> by
> the initializer in the
> 
>    _Cilk_spawn [=](int *Aa, int size){ foo1_c(A, size); }(B, 2);
> 
> case.  The initializer for the closure is a CONSTRUCTOR which contains a
> reference to A, and that is running into trouble because
> extract_free_variables doesn't walk into CONSTRUCTORs.  You probably
> want to switch a lot of your tree walking functions to use walk_tree directly
> rather than try to keep up with all the different kinds of expressions 
> yourself.

Found the bug. I was not utilizing the stabilize_expr's output correctly. Here 
is the fixed patch. I have removed the function pointer and the lang_hooks 
addition. It now just uses copy_tree_body_r for C and C++. It passes all the 
tests for C and C++ on my x86_64 box.

Is this Ok for trunk?

Here are the ChangeLog entries:
gcc/c-family/ChangeLog
2013-11-27  Balaji V. Iyer  <balaji.v.i...@intel.com>

        * cilk.c (cilk_outline): Made this function non-static.
        * c-common.h (cilk_outline): New prototype.
        (c_cilk_install_body_with_frame_cleanup): Added a new parameter.

gcc/ChangeLog
2013-11-27  Balaji V. Iyer  <balaji.v.i...@intel.com>

        * langhooks.h
        (lang_hooks_for_cilkplus::install_body_with_frame_cleanup): Added new
        parameter.

gcc/cp/ChangeLog
2013-11-27  Balaji V. Iyer  <balaji.v.i...@intel.com>

        * cp-tree.h (cilk_valid_spawn): New prototype.
        (gimplify_cilk_spawn): Likewise.
        (cp_cilk_install_body_wframe_cleanup): Likewise.
        (cilk_create_lambda_fn_tmp_var): Likewise.
        (create_try_catch_expr): Likewise.
        * decl.c (finish_function): Insert Cilk function-calls when a
        _Cilk_spawn is used in a function.
        * parser.c (cp_parser_postfix_expression): Added RID_CILK_SPAWN and
        RID_CILK_SYNC cases.
        * cp-cilkplus.c (set_cilk_except_flag): New function.
        (set_cilk_except_data): Likewise.
        (cp_cilk_install_body_wframe_cleanup): Likewise.
        (is_lambda_function): Likewise.
        * except.c (create_try_catch_expr): Likewise.
        * parser.h (IN_CILK_SPAWN): New #define.
        * cp-objcp-common.h (LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN): Likewise.
        * cp-objcp-common.h (LANG_HOOKS_CILKPLUS_CILK_SPEC_COPY_BODY):
        Likewise.
        (LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP): Likewise.
        (LANG_HOOKS_CILKPLUS_FRAME_CLEANUP): Likewise.
        * pt.c (tsubst_expr): Added CILK_SPAWN_STMT and CILK_SYNC_STMT cases.
        * semantics.c (potential_constant_expression_1): Likewise.
        * typeck.c (cp_build_compound_expr): Reject a spawned function in a
        compound expression.
        (check_return_expr): Reject a spawned function in a return expression.

gcc/testsuite/ChangeLog
2013-11-27  Balaji V. Iyer  <balaji.v.i...@intel.com>

        * g++.dg/cilk-plus/CK/catch_exc.cc: New test case.
        * g++.dg/cilk-plus/CK/const_spawn.cc: Likewise.
        * g++.dg/cilk-plus/CK/fib-opr-overload.cc: Likewise.
        * g++.dg/cilk-plus/CK/fib-tplt.cc: Likewise.
        * g++.dg/cilk-plus/CK/lambda_spawns.cc: Likewise.
        * g++.dg/cilk-plus/CK/lambda_spawns_tplt.cc: Likewise.
        * g++.dg/cilk-plus/cilk-plus.exp: Added support to run Cilk Keywords
        test stored in c-c++-common.  Also, added the Cilk runtime's library
        to the ld_library_path.

Thanks,

Balaji V. Iyer.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 664e928..f46008f
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1379,7 +1379,7 @@ extern vec <tree, va_gc> *fix_sec_implicit_args
 extern tree insert_cilk_frame (tree);
 extern void cilk_init_builtins (void);
 extern int gimplify_cilk_spawn (tree *, gimple_seq *, gimple_seq *);
-extern void c_cilk_install_body_w_frame_cleanup (tree, tree);
+extern void c_cilk_install_body_w_frame_cleanup (tree, tree, void *);
 extern bool cilk_detect_spawn_and_unwrap (tree *);
 extern bool cilk_set_spawn_marker (location_t, tree);
 extern tree build_cilk_sync (void);
@@ -1387,5 +1387,5 @@ extern tree build_cilk_spawn (location_t, tree);
 extern tree make_cilk_frame (tree);
 extern tree create_cilk_function_exit (tree, bool, bool);
 extern tree cilk_install_body_pedigree_operations (tree);
-
+extern void cilk_outline (tree, tree *, struct wrapper_data *);
 #endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index c85b5f2..537a07b 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -477,7 +477,7 @@ wrapper_local_cb (const void *k_v, void **vp, void *data)
 
 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN.  */
 
-static void
+void
 cilk_outline (tree inner_fn, tree *stmt_p, struct wrapper_data *wd)
 {
   const tree outer_fn = wd->context;         
@@ -512,8 +512,8 @@ cilk_outline (tree inner_fn, tree *stmt_p, struct 
wrapper_data *wd)
   /* We don't want the private variables any more.  */
   pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
                        &id);
-
-  walk_tree (stmt_p, copy_tree_body_r, &id, NULL);
+  
+  walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
 
   /* See if this function can throw or calls something that should
      not be spawned.  The exception part is only necessary if
@@ -554,10 +554,9 @@ create_cilk_wrapper_body (tree stmt, struct wrapper_data 
*wd)
   for (p = wd->parms; p; p = TREE_CHAIN (p))
     DECL_CONTEXT (p) = fndecl;
 
-  cilk_outline (fndecl, &stmt, wd);
-  stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
   gcc_assert (!DECL_SAVED_TREE (fndecl));
-  lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt);
+  lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt, 
+                                                      (void *) wd);
   gcc_assert (DECL_SAVED_TREE (fndecl));
 
   pop_cfun_to (outer);
@@ -879,7 +878,7 @@ cilk_install_body_pedigree_operations (tree frame_ptr)
    spawn-helper and BODY is the newly created body for FNDECL.  */
 
 void
-c_cilk_install_body_w_frame_cleanup (tree fndecl, tree body)
+c_cilk_install_body_w_frame_cleanup (tree fndecl, tree body, void *wd)
 {
   tree list = alloc_stmt_list ();
   tree frame = make_cilk_frame (fndecl);
@@ -894,6 +893,10 @@ c_cilk_install_body_w_frame_cleanup (tree fndecl, tree 
body)
   
   tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, frame_ptr); 
   append_to_statement_list (detach_expr, &body_list);
+ 
+  cilk_outline (fndecl, &body, (struct wrapper_data *) wd);
+  body = fold_build_cleanup_point_expr (void_type_node, body);
+
   append_to_statement_list (body, &body_list);
   append_to_statement_list (build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR,
                                        body_list, dtor), &list);
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index 5c1090a..480823d
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -25,7 +25,10 @@
 #include "coretypes.h"
 #include "cp-tree.h"
 #include "diagnostic-core.h"
-
+#include "tree-iterator.h"
+#include "tree-inline.h"  /* for copy_tree_body_r.  */
+#include "ggc.h"
+#include "cilk.h"
 
 /* Callback for cp_walk_tree to validate the body of a pragma simd loop
    or _cilk_for loop.
@@ -75,3 +78,90 @@ cpp_validate_cilk_plus_loop (tree body)
                (void *) &valid, NULL);
   return valid;
 }
+
+/* Sets the EXCEPTION bit (0x10) in the FRAME.flags field.  */
+
+static tree
+set_cilk_except_flag (tree frame)
+{
+  tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, 0);
+
+  flags = build2 (MODIFY_EXPR, void_type_node, flags,
+                 build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags,
+                         build_int_cst (TREE_TYPE (flags),
+                                        CILK_FRAME_EXCEPTING)));
+  return flags;
+}
+
+/* Sets the frame.EXCEPT_DATA field to the head of the exception pointer.  */
+
+static tree
+set_cilk_except_data (tree frame)
+{
+  tree except_data = cilk_dot (frame, CILK_TI_FRAME_EXCEPTION, 0);
+  tree uresume_fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
+  tree ret_expr;
+  uresume_fn  = build_call_expr (uresume_fn, 1,
+                                build_int_cst (integer_type_node, 0));
+  ret_expr = build2 (MODIFY_EXPR, void_type_node, except_data, uresume_fn);
+  return ret_expr;
+}
+
+/* Returns true if the FUNCTION_DECL in call_exp, A CALL_EXPR tree is a
+   lambda function.  */
+
+static bool
+is_lambda_fn_p (tree call_exp)
+{
+  if (TREE_CODE (call_exp) != CALL_EXPR)
+    return false;
+  tree call_fn = CALL_EXPR_FN (call_exp);
+  if (TREE_CODE (call_fn) == ADDR_EXPR)
+    call_fn = TREE_OPERAND (call_fn, 0);
+  if (call_fn && LAMBDA_FUNCTION_P (call_fn))
+    return true;
+  return false;
+}
+
+/* Installs BODY into function FNDECL with appropriate exception handling
+   code.  WD holds information of wrapper function used to pass into the
+   outlining function, cilk_outline.  */
+
+void
+cp_cilk_install_body_wframe_cleanup (tree fndecl, tree orig_body, void *wd)
+{
+  tree frame = make_cilk_frame (fndecl);
+  tree dtor = create_cilk_function_exit (frame, false, false);
+  add_local_decl (cfun, frame);
+
+  cfun->language = ggc_alloc_cleared_language_function ();
+  
+  location_t loc = EXPR_LOCATION (orig_body);
+  tree list = alloc_stmt_list ();
+  DECL_SAVED_TREE (fndecl) = list;
+  tree fptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)), 
frame);
+  tree body = cilk_install_body_pedigree_operations (fptr);
+  gcc_assert (TREE_CODE (body) == STATEMENT_LIST);
+  tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, fptr);
+  append_to_statement_list (detach_expr, &body);
+  tree pre_body = NULL_TREE;
+  if (is_lambda_fn_p (orig_body))
+    stabilize_expr (orig_body, &pre_body);
+  else
+    pre_body = orig_body;
+  cilk_outline (fndecl, &pre_body, (struct wrapper_data *) wd);
+  orig_body = fold_build_cleanup_point_expr (void_type_node, orig_body);
+  append_to_statement_list (orig_body, &body);
+  if (flag_exceptions)
+    {
+      tree except_flag = set_cilk_except_flag (frame);
+      tree except_data = set_cilk_except_data (frame);
+      tree catch_list = alloc_stmt_list ();
+      append_to_statement_list (except_flag, &catch_list);
+      append_to_statement_list (except_data, &catch_list);
+      body = create_try_catch_expr (body, catch_list);
+    }
+  append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
+                           &list);
+}
+
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index ee22423..77a66c3 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -154,4 +154,14 @@ extern void cp_common_init_ts (void);
 #undef LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS
 #define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS cp_protect_cleanup_actions
 
+#undef  LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN
+#define LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN gimplify_cilk_spawn
+
+#undef  LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP
+#define LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP  \
+    cilk_detect_spawn_and_unwrap
+
+#undef  LANG_HOOKS_CILKPLUS_FRAME_CLEANUP
+#define LANG_HOOKS_CILKPLUS_FRAME_CLEANUP cp_cilk_install_body_wframe_cleanup
+
 #endif /* GCC_CP_OBJCP_COMMON */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1fc4b59..109110b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5356,6 +5356,7 @@ extern tree begin_eh_spec_block                   (void);
 extern void finish_eh_spec_block               (tree, tree);
 extern tree build_eh_type_type                 (tree);
 extern tree cp_protect_cleanup_actions         (void);
+extern tree create_try_catch_expr               (tree, tree);
 
 /* in expr.c */
 extern tree cplus_expand_constant              (tree);
@@ -6180,11 +6181,17 @@ extern void vtv_build_vtable_verify_fndecl      (void);
 
 /* In cp-cilkplus.c.  */
 extern bool cpp_validate_cilk_plus_loop                (tree);
+extern void cp_cilk_install_body_wframe_cleanup (tree, tree, void *);
 
 /* In cp/cp-array-notations.c */
 extern tree expand_array_notation_exprs         (tree);
 bool cilkplus_an_triplet_types_ok_p             (location_t, tree, tree, tree,
                                                 tree);
+/* In c-family/cilk.c */
+extern bool cilk_valid_spawn                    (tree);
+extern int gimplify_cilk_spawn                  (tree *, gimple_seq *,
+                                                gimple_seq *);
+
 /* -- end of C++ */
 
 #endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9508131..5e3c301 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "plugin.h"
 #include "cgraph.h"
+#include "cilk.h"
 
 /* Possible cases of bad specifiers type used by bad_specifiers. */
 enum bad_spec_place {
@@ -13883,6 +13884,9 @@ finish_function (int flags)
   /* If we're saving up tree structure, tie off the function now.  */
   DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));
 
+  if (fn_contains_cilk_spawn_p (cfun) && !processing_template_decl)
+    cfun->cilk_frame_decl = insert_cilk_frame (fndecl);
+
   finish_fname_decls ();
 
   /* If this function can't throw any exceptions, remember that.  */
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index d7d009b..8ecac62 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1342,4 +1342,22 @@ build_noexcept_spec (tree expr, int complain)
     }
 }
 
+/* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the
+   TRY and CATCH locations.  CATCH_LIST must be a STATEMENT_LIST */
+
+tree
+create_try_catch_expr (tree try_expr, tree catch_list)
+{
+  location_t loc = EXPR_LOCATION (try_expr);
+  gcc_assert (TREE_CODE (catch_list) == STATEMENT_LIST);
+  append_to_statement_list (do_begin_catch (), &catch_list);
+  append_to_statement_list (build_throw (NULL_TREE), &catch_list);
+  tree catch_tf_expr = build_stmt (loc, TRY_FINALLY_EXPR, catch_list, 
+                                  do_end_catch (NULL_TREE));
+  catch_list = build2 (CATCH_EXPR, void_type_node, NULL_TREE,
+                      catch_tf_expr);
+  tree try_catch_expr = build_stmt (loc, TRY_CATCH_EXPR, try_expr, catch_list);
+  return try_catch_expr;
+}
+
 #include "gt-cp-except.h"
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d7092cc..2069e4c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5627,6 +5627,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
   cp_id_kind idk = CP_ID_KIND_NONE;
   tree postfix_expression = NULL_TREE;
   bool is_member_access = false;
+  int saved_in_statement = -1;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -5771,6 +5772,70 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
       }
       break;
 
+    case RID_CILK_SPAWN:
+      {
+       cp_lexer_consume_token (parser->lexer);
+       token = cp_lexer_peek_token (parser->lexer);
+       if (token->type == CPP_SEMICOLON)
+         {
+           error_at (token->location, "%<_Cilk_spawn%> must be followed by an "
+                     "expression");
+           postfix_expression = error_mark_node;
+           break;
+         }
+       else if (!current_function_decl)
+         {
+           error_at (token->location, "%<_Cilk_spawn%> may only be used "
+                     "inside a function");
+           postfix_expression = error_mark_node;
+           break;
+         }
+       else
+         {
+           /* Break or continue statements within this primary expression
+              is not allowed.  */
+           saved_in_statement = parser->in_statement;
+           parser->in_statement = IN_CILK_SPAWN;
+         }
+       /* We set this here so that finish_call_expr can set lambda to a var.
+          if it is not done so.  */
+       cfun->calls_cilk_spawn = 1;
+       postfix_expression = cp_parser_postfix_expression (parser, false, false,
+                                                          false, false, &idk);
+       if (saved_in_statement & IN_CILK_SPAWN)
+         {
+           error_at (token->location, "consecutive %<_Cilk_spawn%> keywords "
+                     "are not permitted");
+           postfix_expression = error_mark_node;
+           cfun->calls_cilk_spawn = 0; 
+         }
+       else
+         {
+           postfix_expression = build_cilk_spawn (token->location, 
+                                                  postfix_expression);
+           if (postfix_expression != error_mark_node) 
+             SET_EXPR_LOCATION (postfix_expression, input_location);
+           parser->in_statement = parser->in_statement & ~IN_CILK_SPAWN;
+         }
+       break;
+      }
+      
+    case RID_CILK_SYNC:
+      if (flag_enable_cilkplus)
+       { 
+         tree sync_expr = build_cilk_sync ();
+         SET_EXPR_LOCATION (sync_expr, 
+                            cp_lexer_peek_token (parser->lexer)->location);
+         finish_expr_stmt (sync_expr);
+       }
+      else
+       error_at (input_location, "_Cilk_sync cannot be used without enabling "
+                 "Cilk Plus");
+      cp_lexer_consume_token (parser->lexer);
+      if (parser->in_statement & IN_CILK_SPAWN)
+       parser->in_statement = parser->in_statement & ~IN_CILK_SPAWN;
+      break;
+
     case RID_BUILTIN_SHUFFLE:
       {
        vec<tree, va_gc> *vec;
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index edd4e6e..e26e350 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -301,6 +301,7 @@ typedef struct GTY(()) cp_parser {
 #define IN_OMP_FOR             8
 #define IN_IF_STMT             16
 #define IN_CILK_SIMD_FOR       32
+#define IN_CILK_SPAWN          64
   unsigned char in_statement;
 
   /* TRUE if we are presently parsing the body of a switch statement.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b58c755..8672129 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13762,6 +13762,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl,
       error ("use %<...%> to expand argument pack");
       RETURN (error_mark_node);
 
+    case CILK_SPAWN_STMT:
+      cfun->calls_cilk_spawn = 1;
+      RETURN (build_cilk_spawn (EXPR_LOCATION (t), RECUR (CILK_SPAWN_FN (t))));
+
+    case CILK_SYNC_STMT:
+      RETURN (build_cilk_sync ());
+
     case COMPOUND_EXPR:
       tmp = RECUR (TREE_OPERAND (t, 0));
       if (tmp == NULL_TREE)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index d871c4d..4f637fb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -10417,6 +10417,8 @@ potential_constant_expression_1 (tree t, bool 
want_rval, tsubst_flags_t flags)
          return false;
       return true;
 
+    case CILK_SYNC_STMT:
+    case CILK_SPAWN_STMT:
     case ARRAY_NOTATION_REF:
       return false;
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a4da037..fd8eac1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6164,6 +6164,17 @@ cp_build_compound_expr (tree lhs, tree rhs, 
tsubst_flags_t complain)
   if (lhs == error_mark_node || rhs == error_mark_node)
     return error_mark_node;
 
+  if (flag_enable_cilkplus
+      && (TREE_CODE (lhs) == CILK_SPAWN_STMT
+         || TREE_CODE (rhs) == CILK_SPAWN_STMT))
+    {
+      location_t loc = (EXPR_HAS_LOCATION (lhs) ? EXPR_LOCATION (lhs)
+                       : EXPR_LOCATION (rhs));
+      error_at (loc,
+               "spawned function call cannot be part of a comma expression");
+      return error_mark_node;
+    }
+
   if (TREE_CODE (rhs) == TARGET_EXPR)
     {
       /* If the rhs is a TARGET_EXPR, then build the compound
@@ -8288,6 +8299,13 @@ check_return_expr (tree retval, bool *no_warning)
 
   *no_warning = false;
 
+  if (flag_enable_cilkplus && retval && TREE_CODE (retval) == CILK_SPAWN_STMT)
+    {
+      error_at (EXPR_LOCATION (retval), "use of %<_Cilk_spawn%> in a return "
+               "statement is not allowed");
+      return NULL_TREE;
+    }
+
   /* A `volatile' function is one that isn't supposed to return, ever.
      (This is a G++ extension, used to get better code for functions
      that call the `volatile' function.)  */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 411cf74..e3c34d9 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -214,7 +214,7 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_OMP_CLAUSE_DTOR hook_tree_tree_tree_null
 #define LANG_HOOKS_OMP_FINISH_CLAUSE hook_void_tree
 
-extern void lhd_install_body_with_frame_cleanup (tree, tree);
+extern void lhd_install_body_with_frame_cleanup (tree, tree, void *);
 extern bool lhd_cilk_detect_spawn (tree *);
 #define LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP lhd_cilk_detect_spawn
 #define LANG_HOOKS_CILKPLUS_FRAME_CLEANUP lhd_install_body_with_frame_cleanup
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 7fe349d..ef6d82d 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -681,7 +681,7 @@ lhd_end_section (void)
    frame cleanup function for _Cilk_spawn.  */
 
 void
-lhd_install_body_with_frame_cleanup (tree, tree)
+lhd_install_body_with_frame_cleanup (tree, tree, void *)
 {
 }
 
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 9539e7d..80bfa66 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -148,7 +148,7 @@ struct lang_hooks_for_cilkplus
 
   /* Function to add the clean up functions after spawn.  The reason why it is
      language dependent is because in C++, it must handle exceptions.  */
-  void (*install_body_with_frame_cleanup) (tree, tree);
+  void (*install_body_with_frame_cleanup) (tree, tree, void *);
 
   /* Function to gimplify a spawned function call.  Returns enum gimplify
      status, but as mentioned in a previous comment, we can't see that type 
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc
new file mode 100644
index 0000000..0633d19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/catch_exc.cc
@@ -0,0 +1,67 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* arm*-*-* 
} } } */
+
+#include <assert.h>
+#include <unistd.h>
+#if HAVE_IO
+#include <cstdio>
+#include <cilk/cilk_api.h>
+#endif
+#include <cstdlib>
+
+
+void func(int volatile* steal_me) 
+{
+  while (! (*steal_me)) 
+    {
+      usleep(2000);
+    }
+#if HAVE_IO
+  printf("Foo executing on %d\n", __cilkrts_get_worker_number());
+#endif
+  throw 5;
+}
+
+void my_test() 
+{
+  volatile int steal_me = 0;
+
+  try 
+    {
+      _Cilk_spawn func(&steal_me);
+#if HAVE_IO
+      printf("Continuation executing on %d\n",
+            __cilkrts_get_worker_number());
+#endif
+      steal_me = 1;
+      _Cilk_sync;
+      goto bad;
+    }
+
+  catch (int x) 
+    {
+#if HAVE_IO
+      printf("We caught x = %d\n", x);
+#endif
+      assert(x == 5);
+    }
+  if (0) 
+    {
+    bad:
+#if HAVE_IO
+      printf("We should not be here!\n");
+#endif
+      __builtin_abort ();
+    }
+}
+
+
+int main() 
+{
+  my_test();
+#if HAVE_IO
+  printf("PASSED\n");
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/const_spawn.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/const_spawn.cc
new file mode 100644
index 0000000..1ea473f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/const_spawn.cc
@@ -0,0 +1,78 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* arm*-*-* 
} } } */
+
+class Rectangle
+{
+  int area_val, h, w;
+  public:
+    Rectangle (int, int);
+    Rectangle (int, int, int);
+    ~Rectangle ();
+    int area ();
+};
+Rectangle::~Rectangle ()
+{
+  h = 0;
+  w = 0;
+  area_val = 0;
+}
+Rectangle::Rectangle (int height, int width)
+{
+  h = height;
+  w = width;
+  area_val = 0;
+}
+
+Rectangle::Rectangle (int height, int width, int area_orig)
+{
+  h = height;
+  w = width;
+  area_val = area_orig;
+}
+
+int Rectangle::area()
+{
+  return (area_val += (h*w));
+}
+
+/* Spawning constructor.  */
+int main1 (void)
+{
+  Rectangle r = _Cilk_spawn Rectangle (4, 3);
+  return r.area();
+}
+ 
+/* Spawning constructor 2.  */
+int main2 (void)
+{
+  Rectangle r (_Cilk_spawn Rectangle (4, 3));
+  return r.area();
+}
+
+/* Spawning copy constructor.  */
+int main3 (void)
+{
+  Rectangle r = _Cilk_spawn Rectangle (4, 3, 2);
+  return r.area ();
+}
+
+/* Spawning copy constructor 2.  */
+int main4 (void)
+{
+  Rectangle r ( _Cilk_spawn Rectangle (4, 3, 2));
+  return r.area();
+}
+
+int main (void)
+{
+  if (main1 () != 12)
+    __builtin_abort ();
+  if (main2 () != 12)
+    __builtin_abort ();
+  if (main3 () != 14)
+    __builtin_abort ();
+  if (main4() != 14)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/fib-opr-overload.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/fib-opr-overload.cc
new file mode 100644
index 0000000..6af4a36
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/fib-opr-overload.cc
@@ -0,0 +1,94 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* arm*-*-* 
} } } */
+
+#if HAVE_IO
+#include <iostream>
+#endif
+
+class Some_Struct
+{
+  int calculated_value;
+  short some_unused_value;
+public:
+  Some_Struct () {
+      this->calculated_value = 0;
+  }
+  Some_Struct (int value) {
+      this->calculated_value = value;
+  }
+  Some_Struct operator=(Some_Struct f) {
+      this->calculated_value = f.calculated_value;
+      return *this;
+  }
+  bool operator!=(Some_Struct f) {
+      return (this->calculated_value != f.calculated_value);
+  }
+  Some_Struct operator+(Some_Struct &f) {
+    Some_Struct z;
+    z.calculated_value = this->calculated_value + f.calculated_value;
+      return z;
+  }
+  Some_Struct operator-(int x) {
+    Some_Struct z;
+    z.calculated_value = this->calculated_value - x;
+    return z;
+  }
+  bool operator<(int x) {
+      return (this->calculated_value < x);
+  }
+  int get_calculated_value () {
+      return this->calculated_value;
+  }
+};
+
+
+template <class T>
+T fibonacci_serial (T f)
+{
+  if (f < 2)
+    return f;
+  T a = fibonacci_serial (f-1);
+  T b = fibonacci_serial (f-2);
+  return (a+b);
+}
+
+template <class T>
+T fibonacci (T f)
+{
+  if (f < 2)
+    return f;
+  T a = _Cilk_spawn fibonacci (f-1);
+  T b = fibonacci (f-2);
+  _Cilk_sync; 
+  return (a+b);
+}
+
+int main (void)
+{
+  Some_Struct f (40), f_serial(40);
+  f = fibonacci (f);
+  f_serial = fibonacci_serial (f_serial);
+  
+  if (f != f_serial)
+    __builtin_abort ();
+  
+  int t = 40, t_serial = 40;
+  t = fibonacci (t);
+  t_serial = fibonacci_serial (t_serial);
+  if (t != t_serial)
+    __builtin_abort ();
+
+  short s = 20, s_serial = 20;
+  s = fibonacci (s);
+  s_serial = fibonacci_serial (s_serial);
+  if (s != s_serial)
+    __builtin_abort ();
+
+#if HAVE_IO
+  std::cout << "Fib_Parallel (40) = " << f.get_calculated_value() << std::endl;
+  std::cout << "Fib_Serial   (40) = " << f_serial.get_calculated_value() 
+    << std::endl;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/fib-tplt.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/fib-tplt.cc
new file mode 100644
index 0000000..dbc2da8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/fib-tplt.cc
@@ -0,0 +1,53 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* 
arm*-*-*-* } } } */
+
+struct fib_struct
+{
+  int x;
+  int *y;
+  int z[3];
+  struct fib_struct *ptr_next;
+  struct fib_struct operator+(struct fib_struct &other) {
+    struct fib_struct z ;
+     z.x = (*this).x + (other.x);
+    return z; 
+  }
+  struct fib_struct operator-(int other) {
+    struct fib_struct z ;
+    z.x = this->x - other;
+    return z;
+  }
+  bool operator<(int number) {
+   return (this->x < number);
+  }
+    
+};
+
+template <typename T>
+T fib (T z) {
+    if (z < 2) return z;
+    T a = _Cilk_spawn fib<T>(z - 1);
+    T b = fib<T>(z - 2);
+    T c = a + b;
+    return (a+b);
+}
+
+
+int sfib(int x)
+{
+  if (x < 2) return x;
+  int a = sfib(x-1);
+  int b = sfib(x-2);
+  return (a+b);
+}
+
+int main () {
+     int z = 30;
+     int parallel_fib = fib<int>(z);
+     int serial_fib = sfib(z);
+    if (serial_fib != parallel_fib) 
+      __builtin_abort ();
+    
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns.cc
new file mode 100644
index 0000000..7448d1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns.cc
@@ -0,0 +1,236 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-std=c++11 -fcilkplus -lcilkrts" { target { i?86-*-* 
x86_64-*-* arm*-*-* } } } */
+#define FIRST_NUMBER 5
+#define SECOND_NUMBER 3
+#define HAVE_IO 0
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+
+int global_var;
+
+void foo1(int *array, int size)
+{
+#if HAVE_IO
+  for (int ii = 0; ii < size; ii++) 
+    printf("%2d\t", array[ii]);
+  printf("\n");
+  fflush (stdout);
+#else
+  if (size != 2)
+    __builtin_abort ();
+  if (array[0] != FIRST_NUMBER)
+    __builtin_abort ();
+  if (array[1] != SECOND_NUMBER)
+    __builtin_abort ();
+#endif
+  global_var++;
+}
+void foo1_c(const int *array, int size)
+{
+#if HAVE_IO
+  for (int ii = 0; ii < size; ii++) 
+    printf("%2d\t", array[ii]);
+  printf("\n");
+  fflush (stdout);
+#else
+  if (size != 2)
+    __builtin_abort ();
+  if (array[0] != FIRST_NUMBER)
+    __builtin_abort ();
+  if (array[1] != SECOND_NUMBER)
+    __builtin_abort ();
+#endif
+  global_var++;
+}
+
+
+int main2 (int argc) {
+  int A[2] = {FIRST_NUMBER, SECOND_NUMBER};
+  int B[2] = {FIRST_NUMBER, SECOND_NUMBER};
+  int main_size = argc+1; /* We know argc is 1, and so 1+1 = 2.  */
+  int q = 0;
+
+  global_var = 0;
+  auto func0 = [=](){ foo1_c(A, 2); };
+  _Cilk_spawn func0();
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func1 = [=](int *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func1 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func2 = [=](int *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func2 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func3 = [=](int *Aa, int size){ int new_size = (size % 2 + 2); 
+                                      foo1(Aa, size); };
+  _Cilk_spawn func3 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func4 = [](int *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func4 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func5 = [](int *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func5 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func6 = [&](int *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func6 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func7 = [&](int *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func7 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func8 = [&](){ foo1(A, 2); };
+  _Cilk_spawn func8 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  /* We ignore the first param here and pass in A from the outer fn.  */
+  auto func9 = [&](int *Aa, int size){ foo1(A, size); };
+  _Cilk_spawn func9 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func10 = [=](){ foo1_c(A, main_size); };
+  _Cilk_spawn func10 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  auto func11 = [&](){ foo1(A, main_size); };
+  _Cilk_spawn func11 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  /* We ignore the first & second param here and pass in A from the 
+     outer fn.  */
+  auto func12 = [&](int *Aa, int size){ foo1(A, main_size); };
+  _Cilk_spawn func12 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [&](int *Aa){ foo1(Aa, 2); }(A);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [&](int *Aa, int size){ foo1(Aa, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [=](int *Aa){ foo1(Aa, 2); }(A);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [=](int *Aa, int size){ foo1(Aa, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  /* We ignore the first param here.  */
+  _Cilk_spawn [=](int *Aa, int size){ foo1_c(A, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  /* We ignore the first and second param here.  */
+  _Cilk_spawn [=](int *Aa, int size){ foo1_c(A, size); }(B, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [&](){ foo1(A, 2); }();
+  [&](){ foo1(A, 2); }();
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [=](){ foo1_c (A, main_size); }();
+  foo1 (A, 2);
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  global_var = 0;
+  _Cilk_spawn [&](){ foo1(A, main_size); }();
+  [&](){ foo1(A, 2); }();
+  _Cilk_sync;
+  if (global_var != 2)
+    return (++q);
+
+  return q;
+}
+
+int main (void)
+{
+  return main2 (1);
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns_tplt.cc 
b/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns_tplt.cc
new file mode 100644
index 0000000..2667f5a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/lambda_spawns_tplt.cc
@@ -0,0 +1,173 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-std=c++11 -fcilkplus -lcilkrts" { target { i?86-*-* 
x86_64-*-* arm*-*-* } } } */
+
+#define FIRST_NUMBER 5
+#define SECOND_NUMBER 3
+#define HAVE_IO 0
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+
+template <class T>
+void foo1(T *array, int size)
+{
+#if HAVE_IO
+  for (int ii = 0; ii < size; ii++) 
+    printf("%2d\t", (int)array[ii]);
+  printf("\n");
+  fflush (stdout);
+#else
+  if (size != 2)
+    __builtin_abort ();
+  if (array[0] != FIRST_NUMBER)
+    __builtin_abort ();
+  if (array[1] != SECOND_NUMBER)
+    __builtin_abort ();
+#endif
+}
+template <class T>
+void foo1_c(const T *array, int size)
+{
+#if HAVE_IO
+  for (int ii = 0; ii < size; ii++) 
+    printf("%2d\t", (int)array[ii]);
+  printf("\n");
+  fflush (stdout);
+#else
+  if (size != 2)
+    __builtin_abort ();
+  if (array[0] != FIRST_NUMBER)
+    __builtin_abort ();
+  if (array[1] != SECOND_NUMBER)
+    __builtin_abort ();
+#endif
+}
+template <class T>
+int main2 (int argc, char **argv) {
+  T A[2] = {FIRST_NUMBER, SECOND_NUMBER};
+  int main_size = argc+1; /* We know argc is 1, and so 1+1 = 2.  */
+  auto func0 = [=](){ foo1_c(A, 2); };
+  _Cilk_spawn func0();
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func1 = [=](T *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func1 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func2 = [=](T *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func2 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func3 = [=](T *Aa, int size){ int new_size = (size % 2 + 2); 
+                                      foo1(Aa, size); };
+  _Cilk_spawn func3 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func4 = [](T *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func4 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func5 = [](T *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func5 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func6 = [&](T *Aa){ foo1(Aa, 2); };
+  _Cilk_spawn func6 (A);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func7 = [&](T *Aa, int size){ foo1(Aa, size); };
+  _Cilk_spawn func7 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func8 = [&](){ foo1(A, 2); };
+  _Cilk_spawn func8 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  /* We ignore the first param here and pass in A from the outer fn.  */
+  auto func9 = [&](T *Aa, int size){ foo1(A, size); };
+  _Cilk_spawn func9 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func10 = [=](){ foo1_c(A, main_size); };
+  _Cilk_spawn func10 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  auto func11 = [&](){ foo1(A, main_size); };
+  _Cilk_spawn func11 ();
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  /* We ignore the first & second param here and pass in A from the 
+     outer fn.  */
+  auto func12 = [&](T *Aa, int size){ foo1(A, main_size); };
+  _Cilk_spawn func12 (A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  _Cilk_spawn [&](T *Aa){ foo1(Aa, 2); }(A);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  _Cilk_spawn [&](T *Aa, int size){ foo1(Aa, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  _Cilk_spawn [=](T *Aa){ foo1(Aa, 2); }(A);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  _Cilk_spawn [=](T *Aa, int size){ foo1(Aa, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  /* We ignore the first param here.  */
+  _Cilk_spawn [=](T *Aa, int size){ foo1_c(A, size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  /* We ignore the first and second param here.  */
+  _Cilk_spawn [=](T *Aa, int size){ foo1_c(A, main_size); }(A, 2);
+  foo1 (A, 2);
+  _Cilk_sync;
+
+  _Cilk_spawn [&](){ foo1(A, 2); }();
+  [&](){ foo1(A, 2); }();
+  _Cilk_sync;
+
+  _Cilk_spawn [=](){ foo1_c(A, main_size); }();
+  foo1 (A, 2);
+  _Cilk_sync;
+       
+  _Cilk_spawn [&](){ foo1(A, main_size); }();
+  [&](){ foo1(A, 2); }();
+  _Cilk_sync;
+
+  return 0;
+}
+
+int main (void)
+{
+  int argc = 1;
+  char **argv = NULL;
+  int x = 1, y = 1, z = 1, q = 1, p = 1;
+  x = main2<char>(argc,argv);
+  y = main2<short>(argc,argv);
+  z = main2<int>(argc,argv);
+  p = main2<long>(argc,argv);
+  q = main2<long long>(argc,argv);
+  return (x+y+z+p+q);
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp 
b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
index a66ec44..a4328d0 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
+++ b/gcc/testsuite/g++.dg/cilk-plus/cilk-plus.exp
@@ -22,6 +22,14 @@ if { ![check_effective_target_cilkplus] } {
     return;
 }
 
+verbose "$tool $libdir" 1
+set library_var "[get_multilibs]"
+# Pointing the ld_library_path to the Cilk Runtime library binaries.
+set ld_library_path "$[get_multilibs]/libcilkrts/.libs"
+
+set ALWAYS_CFLAGS ""
+lappend ALWAYS_CFLAGS "-L${library_var}/libcilkrts/.libs"
+
 dg-init
 # Run the tests that are shared with C.
 g++-dg-runtest [lsort [glob -nocomplain 
$srcdir/c-c++-common/cilk-plus/PS/*.c]] ""
@@ -62,4 +70,23 @@ dg-runtest [lsort [glob -nocomplain 
$srcdir/g++.dg/cilk-plus/AN/*.cc]] " -g -O3
 dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/AN/*.cc]] " -O3 
-ftree-vectorize -fcilkplus -g" " "
 dg-finish
 
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O1 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O2 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -O3 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g 
-O2 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/g++.dg/cilk-plus/CK/*.cc]] " -g 
-O3 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-O1 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-O2 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-O3 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-g -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-g -O2 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " 
-g -O3 -fcilkplus $ALWAYS_CFLAGS" " "
+dg-finish
 unset TEST_EXTRA_LIBS
 

Reply via email to