Commit 6d840d99 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/56217 (ICE: OpenMP: when combining shared() and a move constructor)

	PR middle-end/56217
	* omp-low.c (use_pointer_for_field): Return false if
	lower_send_shared_vars doesn't generate any copy-out code.

	* g++.dg/gomp/pr56217.C: New test.

	* testsuite/libgomp.c++/pr56217.C: New test.

From-SVN: r195796
parent ca4a4fe9
2013-02-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56217
* omp-low.c (use_pointer_for_field): Return false if
lower_send_shared_vars doesn't generate any copy-out code.
2013-02-06 Tom de Vries <tom@codesourcery.com> 2013-02-06 Tom de Vries <tom@codesourcery.com>
PR rtl-optimization/56131 PR rtl-optimization/56131
......
...@@ -757,12 +757,20 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx) ...@@ -757,12 +757,20 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
if (TREE_ADDRESSABLE (decl)) if (TREE_ADDRESSABLE (decl))
return true; return true;
/* lower_send_shared_vars only uses copy-in, but not copy-out
for these. */
if (TREE_READONLY (decl)
|| ((TREE_CODE (decl) == RESULT_DECL
|| TREE_CODE (decl) == PARM_DECL)
&& DECL_BY_REFERENCE (decl)))
return false;
/* Disallow copy-in/out in nested parallel if /* Disallow copy-in/out in nested parallel if
decl is shared in outer parallel, otherwise decl is shared in outer parallel, otherwise
each thread could store the shared variable each thread could store the shared variable
in its own copy-in location, making the in its own copy-in location, making the
variable no longer really shared. */ variable no longer really shared. */
if (!TREE_READONLY (decl) && shared_ctx->is_nested) if (shared_ctx->is_nested)
{ {
omp_context *up; omp_context *up;
...@@ -785,11 +793,10 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx) ...@@ -785,11 +793,10 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
} }
} }
/* For tasks avoid using copy-in/out, unless they are readonly /* For tasks avoid using copy-in/out. As tasks can be
(in which case just copy-in is used). As tasks can be
deferred or executed in different thread, when GOMP_task deferred or executed in different thread, when GOMP_task
returns, the task hasn't necessarily terminated. */ returns, the task hasn't necessarily terminated. */
if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx)) if (is_task_ctx (shared_ctx))
{ {
tree outer; tree outer;
maybe_mark_addressable_and_ret: maybe_mark_addressable_and_ret:
......
2013-02-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56217
* g++.dg/gomp/pr56217.C: New test.
2013-02-05 Jakub Jelinek <jakub@redhat.com> 2013-02-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56205 PR tree-optimization/56205
......
// PR middle-end/56217
// { dg-do compile }
// { dg-options "-fopenmp" }
struct S { int *p; S (); S (S &); };
S
foo ()
{
S s;
#pragma omp task shared (s)
s.p = 0;
return s;
}
2013-02-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56217
* testsuite/libgomp.c++/pr56217.C: New test.
2013-02-01 Alan Modra <amodra@gmail.com> 2013-02-01 Alan Modra <amodra@gmail.com>
* task.c (GOMP_task, GOMP_taskwait): Comment. * task.c (GOMP_task, GOMP_taskwait): Comment.
......
// PR middle-end/56217
// { dg-do run }
// { dg-options "-std=c++0x" }
extern "C" void abort ();
template <typename T>
struct ptr {
T *p;
ptr () : p () {}
ptr (ptr &) = delete;
ptr (ptr &&o) : p(o) {}
operator T * () { return p; }
};
int a[6] = { 100, 101, 102, 103, 104, 105 };
static ptr<int>
f ()
{
ptr<int> pt;
#pragma omp task shared (pt)
pt.p = a + 2;
#pragma omp taskwait
return pt;
}
int
main ()
{
ptr<int> pt;
#pragma omp parallel
#pragma omp single
if (f () != a + 2 || *f () != 102)
abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment