aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-12-29 11:53:36 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-12-29 11:53:36 +0100
commita4983b7ad84e96ef8914e1d027d7b33f7fb5c4a3 (patch)
treec8e09b21dc642ed014458527c995efb184fca84e /gcc
parent2fda71537b379f16b09ca38a2020ff51ca1e99bf (diff)
downloadgcc-a4983b7ad84e96ef8914e1d027d7b33f7fb5c4a3.zip
gcc-a4983b7ad84e96ef8914e1d027d7b33f7fb5c4a3.tar.gz
gcc-a4983b7ad84e96ef8914e1d027d7b33f7fb5c4a3.tar.bz2
re PR ipa/88586 (ICE: Segmentation fault (in free_lang_data_in_decl))
PR ipa/88586 * omp-low.c (lower_omp_task_reductions): Set DECL_CONTEXT on field and ifield. Update TYPE_ALIGN from alignment of field, ifield or bfield. * g++.dg/gomp/pr88586.C: New test. From-SVN: r267461
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/omp-low.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr88586.C77
4 files changed, 99 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61a99be..fd2c230 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/88586
+ * omp-low.c (lower_omp_task_reductions): Set DECL_CONTEXT on field
+ and ifield. Update TYPE_ALIGN from alignment of field, ifield or
+ bfield.
+
2018-12-28 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.h (ADDITIONAL_REGISTER_NAMES): Add
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b406ce7..4517fc1 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -7011,6 +7011,12 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
*last = field;
DECL_CHAIN (field) = ifield;
last = &DECL_CHAIN (ifield);
+ DECL_CONTEXT (field) = record_type;
+ if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
+ SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
+ DECL_CONTEXT (ifield) = record_type;
+ if (TYPE_ALIGN (record_type) < DECL_ALIGN (ifield))
+ SET_TYPE_ALIGN (record_type, DECL_ALIGN (ifield));
}
for (int pass = 0; pass < 2; pass++)
{
@@ -7036,12 +7042,16 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
else
SET_DECL_ALIGN (field, TYPE_ALIGN (type));
DECL_CONTEXT (field) = record_type;
+ if (TYPE_ALIGN (record_type) < DECL_ALIGN (field))
+ SET_TYPE_ALIGN (record_type, DECL_ALIGN (field));
*last = field;
last = &DECL_CHAIN (field);
tree bfield
= build_decl (OMP_CLAUSE_LOCATION (c), FIELD_DECL, NULL_TREE,
boolean_type_node);
DECL_CONTEXT (bfield) = record_type;
+ if (TYPE_ALIGN (record_type) < DECL_ALIGN (bfield))
+ SET_TYPE_ALIGN (record_type, DECL_ALIGN (bfield));
*last = bfield;
last = &DECL_CHAIN (bfield);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc6e687..4e66cf8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/88586
+ * g++.dg/gomp/pr88586.C: New test.
+
2018-12-28 David Edelsohn <dje.gcc@gmail.com>
* c-c++-common/ident-1b.c: XFAIL AIX and Darwin.
diff --git a/gcc/testsuite/g++.dg/gomp/pr88586.C b/gcc/testsuite/g++.dg/gomp/pr88586.C
new file mode 100644
index 0000000..2d1b47b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr88586.C
@@ -0,0 +1,77 @@
+// PR ipa/88586
+// { dg-do compile { target lto } }
+// { dg-options "-fopenmp -flto" }
+
+extern "C" int omp_get_cancellation ();
+extern "C" int omp_get_thread_num ();
+extern "C" void abort ();
+
+struct A { A (); ~A (); A (const A &); static int cnt1, cnt2, cnt3; int a; };
+int A::cnt1;
+int A::cnt2;
+int A::cnt3;
+A::A () : a (0)
+{
+ #pragma omp atomic
+ cnt1++;
+}
+A::A (const A &x) : a (x.a)
+{
+ #pragma omp atomic
+ cnt2++;
+}
+A::~A ()
+{
+ #pragma omp atomic
+ cnt3++;
+}
+#pragma omp declare reduction (+: A: omp_out.a += omp_in.a)
+
+void
+foo (int x)
+{
+ A a, b[2];
+ int d = 1;
+ long int e[2] = { 1L, 1L };
+ int c = 0;
+ #pragma omp parallel
+ {
+ if (x && omp_get_thread_num () == 0)
+ {
+ for (int i = 0; i < 10000000; ++i)
+ asm volatile ("");
+ c = 1;
+ #pragma omp cancel parallel
+ }
+ #pragma omp for reduction (task, +: a, b) reduction (task, *: d, e)
+ for (int i = 0; i < 64; i++)
+ #pragma omp task in_reduction (+: a, b) in_reduction (*: d, e)
+ {
+ a.a++;
+ b[0].a += 2;
+ b[1].a += 3;
+ d *= ((i & 7) == 0) + 1;
+ e[0] *= ((i & 7) == 3) + 1;
+ e[1] *= ((i & 3) == 2) + 1;
+ }
+ if (x && omp_get_cancellation ())
+ abort ();
+ }
+ if (!c)
+ {
+ if (a.a != 64 || b[0].a != 128 || b[1].a != 192)
+ abort ();
+ if (d != 256 || e[0] != 256L || e[1] != 65536L)
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int c1 = A::cnt1, c2 = A::cnt2, c3 = A::cnt3;
+ volatile int zero = 0;
+ foo (zero);
+ if (A::cnt1 + A::cnt2 - c1 - c2 != A::cnt3 - c3)
+ abort ();
+}