From 6d840d998086aa54b0a43c45b7a323f0408bf308 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 6 Feb 2013 11:34:53 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++++ gcc/omp-low.c | 15 ++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/gomp/pr56217.C | 14 ++++++++++ libgomp/ChangeLog | 5 ++++ libgomp/testsuite/libgomp.c++/pr56217.C | 36 +++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gomp/pr56217.C create mode 100644 libgomp/testsuite/libgomp.c++/pr56217.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44e77f9986b..0865a81addf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-02-06 Jakub Jelinek + + 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 PR rtl-optimization/56131 diff --git a/gcc/omp-low.c b/gcc/omp-low.c index e09024af620..ef4ed5e98ac 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -757,12 +757,20 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx) if (TREE_ADDRESSABLE (decl)) 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 decl is shared in outer parallel, otherwise each thread could store the shared variable in its own copy-in location, making the variable no longer really shared. */ - if (!TREE_READONLY (decl) && shared_ctx->is_nested) + if (shared_ctx->is_nested) { 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 - (in which case just copy-in is used). As tasks can be + /* For tasks avoid using copy-in/out. As tasks can be deferred or executed in different thread, when GOMP_task returns, the task hasn't necessarily terminated. */ - if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx)) + if (is_task_ctx (shared_ctx)) { tree outer; maybe_mark_addressable_and_ret: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc716f97bb9..a2a2bb9515d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-02-06 Jakub Jelinek + + PR middle-end/56217 + * g++.dg/gomp/pr56217.C: New test. + 2013-02-05 Jakub Jelinek PR tree-optimization/56205 diff --git a/gcc/testsuite/g++.dg/gomp/pr56217.C b/gcc/testsuite/g++.dg/gomp/pr56217.C new file mode 100644 index 00000000000..03dfc5f180b --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr56217.C @@ -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; +} diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 2bbb789c1a4..b0dc764c9c1 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2013-02-06 Jakub Jelinek + + PR middle-end/56217 + * testsuite/libgomp.c++/pr56217.C: New test. + 2013-02-01 Alan Modra * task.c (GOMP_task, GOMP_taskwait): Comment. diff --git a/libgomp/testsuite/libgomp.c++/pr56217.C b/libgomp/testsuite/libgomp.c++/pr56217.C new file mode 100644 index 00000000000..19da9185350 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr56217.C @@ -0,0 +1,36 @@ +// PR middle-end/56217 +// { dg-do run } +// { dg-options "-std=c++0x" } + +extern "C" void abort (); + +template +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 +f () +{ + ptr pt; + #pragma omp task shared (pt) + pt.p = a + 2; + #pragma omp taskwait + return pt; +} + +int +main () +{ + ptr pt; + #pragma omp parallel + #pragma omp single + if (f () != a + 2 || *f () != 102) + abort (); +}