Index: gcc/c-family/cilk.c
===================================================================
--- gcc/c-family/cilk.c	(revision 231902)
+++ gcc/c-family/cilk.c	(working copy)
@@ -192,7 +192,7 @@
   switch (TREE_CODE_CLASS (code))
     {
     case tcc_expression:
-      return code == ADDR_EXPR;
+      return code == ADDR_EXPR || code == COMPOUND_EXPR;
     case tcc_comparison:
       /* We need the spawn as operand 0 for now.   That's where it
 	 appears in the only case we really care about, conversion
@@ -252,6 +252,78 @@
   return spawn_found;
 }
 
+static bool
+is_conversion_operator_function_decl_p (tree t) {
+  if (TREE_CODE (t) != FUNCTION_DECL)
+    return false;
+
+  return DECL_NAME (t) && TREE_LANG_FLAG_4 (DECL_NAME (t));
+}
+
+static bool
+is_conversion_operator_call_p (tree t) {
+  tree fndecl;
+
+  if (TREE_CODE (t) != CALL_EXPR)
+    return false;
+
+  fndecl = TREE_OPERAND (CALL_EXPR_FN (t), 0);
+  return call_expr_nargs (t) == 1
+	 && is_conversion_operator_function_decl_p (fndecl);
+}
+
+static bool
+is_unary_constructor_aggr_init_p (tree t) {
+  if (TREE_CODE (t) != AGGR_INIT_EXPR)
+    return false;
+
+  return VL_EXP_OPERAND_LENGTH (t) == 5 && TREE_LANG_FLAG_0 (t);
+}
+
+static bool
+is_conversion_operator_aggr_init_p (tree t) {
+  tree fn;
+
+  if (TREE_CODE (t) != AGGR_INIT_EXPR)
+    return false;
+
+  fn = TREE_OPERAND (t, 1);
+  return VL_EXP_OPERAND_LENGTH (t) == 4
+	 && TREE_CODE (fn) == ADDR_EXPR
+	 && is_conversion_operator_function_decl_p (TREE_OPERAND (fn, 0));
+}
+
+static tree
+find_spawn (tree exp)
+{
+  /* Happens with C++ TARGET_EXPR.  */
+  if (exp == NULL_TREE)
+    return exp;
+
+  else if (is_unary_constructor_aggr_init_p (exp))
+    return find_spawn (TREE_OPERAND (exp, 4));
+
+  else if (is_conversion_operator_aggr_init_p (exp))
+    return find_spawn (TREE_OPERAND (exp, 3));
+
+  else if (is_conversion_operator_call_p (exp))
+    return find_spawn (CALL_EXPR_ARG (exp, 0));
+
+  else if (cilk_ignorable_spawn_rhs_op (exp))
+    return find_spawn (TREE_OPERAND (exp, 0));
+
+  else if (TREE_CODE (exp) == TARGET_EXPR)
+    return find_spawn (TARGET_EXPR_INITIAL (exp));
+
+  else if (TREE_CODE (exp) == CLEANUP_POINT_EXPR
+	   || TREE_CODE (exp) == EXPR_STMT)
+    return find_spawn (TREE_OPERAND (exp, 0));
+
+  else
+    return exp;
+}
+
+
 /* Returns true if *EXP0 is a recognized form of spawn.  Recognized forms are,
    after conversion to void, a call expression at outer level or an assignment
    at outer level with the right hand side being a spawned call.
@@ -275,20 +347,7 @@
   if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
     exp = TREE_OPERAND (exp, 1);
 
-  while (cilk_ignorable_spawn_rhs_op (exp))
-    exp = TREE_OPERAND (exp, 0);
-
-  if (TREE_CODE (exp) == TARGET_EXPR)
-    if (TARGET_EXPR_INITIAL (exp)
-	&& TREE_CODE (TARGET_EXPR_INITIAL (exp)) != AGGR_INIT_EXPR)
-      exp = TARGET_EXPR_INITIAL (exp);
-
-  /* Happens with C++ TARGET_EXPR.  */
-  if (exp == NULL_TREE)
-    return false;
-
-  while (TREE_CODE (exp) == CLEANUP_POINT_EXPR || TREE_CODE (exp) == EXPR_STMT)
-    exp = TREE_OPERAND (exp, 0);
+  exp = find_spawn (exp);
   
   /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around 
      it, or return false.  */
@@ -592,6 +651,11 @@
   for (p = wd->parms; p; p = TREE_CHAIN (p))
     DECL_CONTEXT (p) = fndecl;
 
+  /* The statement containing the spawn expression might create temporaries with
+     destructors defined; if so we need to add a CLEANUP_POINT_EXPR to ensure
+     the expression is properly gimplified.  */
+  stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
+
   gcc_assert (!DECL_SAVED_TREE (fndecl));
   cilk_install_body_with_frame_cleanup (fndecl, stmt, (void *) wd);
   gcc_assert (DECL_SAVED_TREE (fndecl));
@@ -1246,6 +1310,21 @@
       return;
 
     case AGGR_INIT_EXPR:
+      {
+	int len = 0;
+	int ii = 0;
+	extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
+	if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
+	  {
+	    len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
+
+	    for (ii = 3; ii < len; ii++)
+	      extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
+	    extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
+	  }
+	break;
+      }
+
     case CALL_EXPR:
       {
 	int len = 0;
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc	(revision 0)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc	(working copy)
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++11 -fcilkplus" } */
+
+struct A1 {
+  A1 () {}
+  A1 (const A1&) {}
+};
+
+A1 fa1 () {
+  return A1 ();
+}
+
+struct A2 {
+  A2 () {}
+  A2 (A2&&) {}
+};
+
+A2 fa2 () {
+  A2 ();
+}
+
+struct B1 {
+};
+
+B1 fb1 () {
+  return B1 ();
+}
+
+struct A3 {
+  A3 (const B1&) {}
+};
+
+struct A4 {
+  A4 (B1) {}
+};
+
+struct B2 {
+  B2 () {}
+  B2 (const B2&) {}
+};
+
+B2 fb2 () {
+  return B2 ();
+}
+
+struct A5 {
+  A5 (B2) {}
+};
+
+void t1 () {
+  A1 a1 = _Cilk_spawn fa1 ();
+}
+
+void t2 () {
+  A2 a2 = _Cilk_spawn fa2 ();
+}
+
+void t3 () {
+  A3 a3 = _Cilk_spawn fb1 ();
+}
+
+void t4 () {
+  A4 a4 = _Cilk_spawn fb1 ();
+}
+
+void t5 () {
+  A5 a5 = _Cilk_spawn fb2 ();
+}
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc	(revision 0)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc	(working copy)
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+struct A1 {
+};
+
+struct A2 {
+  A2 () {}
+  A2 (const A2&) {}
+};
+
+struct B1 {
+  operator A1 () {
+    return A1 ();
+  }
+};
+
+B1 fb1 () {
+  return B1 ();
+}
+
+struct B2 {
+  operator A2 () {
+    return A2 ();
+  }
+};
+
+B2 fb2 () {
+  return B2 ();
+}
+
+void t1 () {
+  A1 a1 = _Cilk_spawn fb1 ();
+}
+
+void t2 () {
+  A2 a2 = _Cilk_spawn fb2 ();
+}
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr69048.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr69048.cc	(revision 0)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr69048.cc	(working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+struct A {
+  ~A () {}
+};
+
+A f () {
+  return A ();
+}
+
+void t1 () {
+  _Cilk_spawn f ();
+}
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc	(revision 231902)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc	(working copy)
@@ -11,7 +11,7 @@
 
 int main()
 {
-  std::vector<double> x = _Cilk_spawn f(); /* { dg-error "invalid use of" } */
+  std::vector<double> x = _Cilk_spawn f ();
   std::vector<double> y = f();
   _Cilk_sync;
   return 0;
