re PR c++/36523 (OpenMP task construct fails to instantiate copy constructor)
authorJakub Jelinek <jakub@redhat.com>
Fri, 20 Jun 2008 02:18:07 +0000 (04:18 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 20 Jun 2008 02:18:07 +0000 (04:18 +0200)
PR c++/36523
* cgraphunit.c (cgraph_process_new_functions): Don't clear
node->needed and node->reachable.
* cgraphbuild.c (record_reference): Handle OMP_PARALLEL and OMP_TASK.
* omp-low.c (delete_omp_context): Call finalize_task_copyfn.
(expand_task_call): Don't call expand_task_copyfn.
(expand_task_copyfn): Renamed to...
(finalize_task_copyfn): ... this.

* testsuite/libgomp.c++/task-7.C: New function.

From-SVN: r136977

gcc/ChangeLog
gcc/cgraphbuild.c
gcc/cgraphunit.c
gcc/omp-low.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/task-7.C [new file with mode: 0644]

index d9f6157cb48da6ace5e8852c2abe530fc2e27200..74a81618ce2c91d796a4426e71bdfe872112c5ab 100644 (file)
@@ -1,3 +1,14 @@
+2008-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/36523
+       * cgraphunit.c (cgraph_process_new_functions): Don't clear
+       node->needed and node->reachable.
+       * cgraphbuild.c (record_reference): Handle OMP_PARALLEL and OMP_TASK.
+       * omp-low.c (delete_omp_context): Call finalize_task_copyfn.
+       (expand_task_call): Don't call expand_task_copyfn.
+       (expand_task_copyfn): Renamed to...
+       (finalize_task_copyfn): ... this.
+
 2008-06-19  Jan Hubicka  <jh@suse.cz>
 
        * builtins.c (expand_builtin_nonlocal_goto): Stabilize r_sp before
index e37ca86f51d41d1d7de878b48aaf47544a2b9eed..19e198344b66402fd41a7ef209db24f6653d32d6 100644 (file)
@@ -62,6 +62,24 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
        }
       break;
 
+    case OMP_PARALLEL:
+      if (flag_unit_at_a_time)
+       {
+         if (OMP_PARALLEL_FN (*tp))
+           cgraph_mark_needed_node (cgraph_node (OMP_PARALLEL_FN (*tp)));
+       }
+      break;
+
+    case OMP_TASK:
+      if (flag_unit_at_a_time)
+       {
+         if (OMP_TASK_FN (*tp))
+           cgraph_mark_needed_node (cgraph_node (OMP_TASK_FN (*tp)));
+         if (OMP_TASK_COPYFN (*tp))
+           cgraph_mark_needed_node (cgraph_node (OMP_TASK_COPYFN (*tp)));
+       }
+      break;
+
     default:
       /* Save some cycles by not walking types and declaration as we
         won't find anything useful there anyway.  */
index 6b00bd59c41061991ed71aa354043f5aced99080..2dcccc1bd93144c814f4253fdb48e32dfcbb7169 100644 (file)
@@ -443,7 +443,6 @@ cgraph_process_new_functions (void)
             it into reachable functions list.  */
 
          node->next_needed = NULL;
-         node->needed = node->reachable = false;
          cgraph_finalize_function (fndecl, false);
          cgraph_mark_reachable_node (node);
          output = true;
index 09b7260a66e7a77368b0f9689b9f5bb4329db537..db5f8584405c6f89f8cf8a9525e7270575905d1b 100644 (file)
@@ -1188,6 +1188,37 @@ new_omp_context (tree stmt, omp_context *outer_ctx)
   return ctx;
 }
 
+static void maybe_catch_exception (tree *stmt_p);
+
+/* Finalize task copyfn.  */
+
+static void
+finalize_task_copyfn (tree task_stmt)
+{
+  struct function *child_cfun;
+  tree child_fn, old_fn;
+
+  child_fn = OMP_TASK_COPYFN (task_stmt);
+  if (child_fn == NULL_TREE)
+    return;
+
+  child_cfun = DECL_STRUCT_FUNCTION (child_fn);
+
+  /* Inform the callgraph about the new function.  */
+  DECL_STRUCT_FUNCTION (child_fn)->curr_properties
+    = cfun->curr_properties;
+
+  old_fn = current_function_decl;
+  push_cfun (child_cfun);
+  current_function_decl = child_fn;
+  gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
+  maybe_catch_exception (&BIND_EXPR_BODY (DECL_SAVED_TREE (child_fn)));
+  pop_cfun ();
+  current_function_decl = old_fn;
+
+  cgraph_add_new_function (child_fn, false);
+}
+
 /* Destroy a omp_context data structures.  Called through the splay tree
    value delete callback.  */
 
@@ -1218,6 +1249,9 @@ delete_omp_context (splay_tree_value value)
        DECL_ABSTRACT_ORIGIN (t) = NULL;
     }
 
+  if (is_task_ctx (ctx))
+    finalize_task_copyfn (ctx->stmt);
+
   XDELETE (ctx);
 }
 
@@ -2882,35 +2916,6 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 }
 
 
-static void maybe_catch_exception (tree *stmt_p);
-
-
-/* Finalize task copyfn.  */
-
-static void
-expand_task_copyfn (tree task_stmt)
-{
-  struct function *child_cfun;
-  tree child_fn, old_fn;
-
-  child_fn = OMP_TASK_COPYFN (task_stmt);
-  child_cfun = DECL_STRUCT_FUNCTION (child_fn);
-
-  /* Inform the callgraph about the new function.  */
-  DECL_STRUCT_FUNCTION (child_fn)->curr_properties
-    = cfun->curr_properties;
-
-  old_fn = current_function_decl;
-  push_cfun (child_cfun);
-  current_function_decl = child_fn;
-  gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
-  maybe_catch_exception (&BIND_EXPR_BODY (DECL_SAVED_TREE (child_fn)));
-  pop_cfun ();
-  current_function_decl = old_fn;
-
-  cgraph_add_new_function (child_fn, false);
-}
-
 /* Build the function call to GOMP_task to actually
    generate the task operation.  BB is the block where to insert the code.  */
 
@@ -2922,9 +2927,6 @@ expand_task_call (basic_block bb, tree entry_stmt)
 
   clauses = OMP_TASK_CLAUSES (entry_stmt);
 
-  if (OMP_TASK_COPYFN (entry_stmt))
-    expand_task_copyfn (entry_stmt);
-
   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
   if (c)
     cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
index 784d59f933df6db7099d376474883bb6f835edab..ed27454354eab84596b9456dc6af99a330a4bf70 100644 (file)
@@ -2,6 +2,9 @@
 
        * testsuite/libgomp.c/nqueens-1.c: New test.
 
+       PR c++/36523
+       * testsuite/libgomp.c++/task-7.C: New function.
+
 2008-06-17  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * configure: Regenerate.
diff --git a/libgomp/testsuite/libgomp.c++/task-7.C b/libgomp/testsuite/libgomp.c++/task-7.C
new file mode 100644 (file)
index 0000000..e9828cd
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/36523
+// { dg-do run }
+
+template<typename T>
+struct A
+{
+  A() { }
+  A(const A&) { }
+  void foo() { }
+};
+
+int main()
+{
+  A<int> a;
+  #pragma omp task firstprivate (a)
+    a.foo();
+  return 0;
+}