This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] Fix another EH related gomp ICE (PR tree-optimization/31769)


Hi!

This is similar to PR30558, but the invalid prev_try (pointing to
an outer ERT_TRY region accros an outer ERT_MUST_NOT_THROW region)
was introduced during inlining (duplicate_eh_regions) rather than
the initial EH tree creation.
ERT_MUST_NOT_THROW can't be crossed with an exception, so
if there isn't any ERT_TRY inside it, we need to keep it NULL.

The problem only occurs in 4.2/4.1.x-RH, as trunk inlines at different time,
still IMHO it should be fixed there as well.

Bootstrapped/regtested on x86_64-linux, ok for trunk/4.2?

2007-05-22  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/31769
	* except.c (duplicate_eh_regions): Clear prev_try if
	ERT_MUST_NOT_THROW region is inside of ERT_TRY region.

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

--- gcc/except.c.jj	2007-02-21 09:37:48.000000000 +0100
+++ gcc/except.c	2007-05-22 13:46:51.000000000 +0200
@@ -1005,7 +1005,11 @@ duplicate_eh_regions (struct function *i
     for (prev_try = VEC_index (eh_region, cfun->eh->region_array, outer_region);
          prev_try && prev_try->type != ERT_TRY;
 	 prev_try = prev_try->outer)
-      ;
+      if (prev_try->type == ERT_MUST_NOT_THROW)
+	{
+	  prev_try = NULL;
+	  break;
+	}
 
   /* Remap all of the internal catch and cleanup linkages.  Since we 
      duplicate entire subtrees, all of the referenced regions will have
--- gcc/testsuite/g++.dg/gomp/pr31769.C.jj	2007-05-22 16:18:11.000000000 +0200
+++ gcc/testsuite/g++.dg/gomp/pr31769.C	2007-05-22 16:18:00.000000000 +0200
@@ -0,0 +1,61 @@
+// PR tree-optimization/31769
+// { dg-options "-O2 -fopenmp" }
+// { dg-do compile }
+
+struct B
+{
+  B () {}
+  virtual ~B () {}
+};
+struct C
+{
+  C (int x, int y) {}
+};
+template<typename T, int U>
+struct D
+{
+  D () {}
+  ~D () {}
+};
+struct E
+{
+  E () {}
+  ~E () {}
+  D<int, 1> e;
+};
+struct A
+{
+  B *b;
+  A () { b = __null; }
+  ~A () { if (b != __null) delete b; }
+};
+struct F : public A
+{
+  explicit F (int x) { foo (0); }
+  F (const F &x) {}
+  F (F &x, C y) {}
+  F operator () (C x) const
+  {
+    return F (const_cast<F &>(*this), x);
+  }
+  template <typename U> F & operator+= (const U &);
+  void foo (int);
+  E f;
+};
+
+int
+main ()
+{
+  try
+  {
+    F f (10);
+    F g (10);
+    C h (0, 9);
+#pragma omp parallel for
+    for (int i = 0; i < 2; ++i)
+      g += f (h);
+  }
+  catch (int &e)
+  {
+  }
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]