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
This commit is contained in:
Jakub Jelinek 2013-02-06 11:34:53 +01:00 committed by Jakub Jelinek
parent ca4a4fe903
commit 6d840d9980
6 changed files with 77 additions and 4 deletions

View file

@ -1,3 +1,9 @@
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

View file

@ -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)
} }
} }
/* 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:

View file

@ -1,3 +1,8 @@
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

View file

@ -0,0 +1,14 @@
// 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;
}

View file

@ -1,3 +1,8 @@
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.

View file

@ -0,0 +1,36 @@
// 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 ();
}