re PR ipa/88586 (ICE: Segmentation fault (in free_lang_data_in_decl))
authorJakub Jelinek <jakub@redhat.com>
Sat, 29 Dec 2018 10:53:36 +0000 (11:53 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 29 Dec 2018 10:53:36 +0000 (11:53 +0100)
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

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/pr88586.C [new file with mode: 0644]

index 61a99be3943cef7da2f4c71a630184c886ba1b15..fd2c23073c5fd4ec2d5e2159c658cf03891f5f97 100644 (file)
@@ -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
index b406ce781f6d209aba5de9c9782cd2340899498c..4517fc1bb8c6f30a602b6ed5ecb5da8c287c5da9 100644 (file)
@@ -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);
        }
index dc6e687294fc165f315ca8e66526e089b472b3d4..4e66cf8295e212436fdcff1c70ea461da1ecc659 100644 (file)
@@ -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 (file)
index 0000000..2d1b47b
--- /dev/null
@@ -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 ();
+}