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 EH prev_try handling (PR tree-optimization/30558)


Hi!

On the attached testcase we have before the eh lowering:

  try
    {
      __comp_ctor  (&gD.2573);
      .omp_data_o.2D.2651.gD.2648 = &gD.2573;
      #pragma omp parallel shared(gD.2573) [child fn: main.omp_fn.0D.2645 (.omp_data_o.2D.2651)]
      try
        {
          .omp_data_iD.2647 = &.omp_data_o.2D.2651;
          try
            {
              #pragma omp for nowait
              for (iD.2583 = 0; iD.2583 <= 9; iD.2583 = iD.2583 + 1)
              __comp_ctor  (&jD.2584, iD.2583);
              try
                {
...
                }
              finally
                {
                  __comp_dtor  (&jD.2584);
                }
              OMP_CONTINUE
            }
          catch
            {
              <<<eh_filter ()>>>
                {
                  terminate ();
                }
            }
          OMP_RETURN [nowait]
        }
      catch
        {
          <<<eh_filter ()>>>
            {
              terminate ();
            }
        }
      OMP_RETURN
    }
  catch
    {
      catch (intD.2)    
        {
          D.2599 = __cxa_begin_catch (<<<exception object>>>);
          e.0D.2595 = (intD.2 *) D.2599;
          eD.2592 = e.0D.2595;
          __cxa_end_catch ();
        }
    }

Eventhough terminate really won't return, EH lowering creates
abnormal EH edges from __comp_dtor (&jD.2584)'s BB to the BB
containing __cxa_begin_catch, as when the outermost try .. catch
is lowered, prev_try in the state is set to that ERT_TRY region
and nothing ever clears it.  This causes various ICEs during omp
expand, as the omp parallel region really is not a single entry
single exit because of that EH edge.  Unmodified gcc ICEs in
duplicate_eh_edges, because REMAP (cur->u.cleanup.prev_try);
is not representable with the new EH regions, when I conditionalized
this it ICEd a short while afterwards (because pred edges of
the __cxa_begin_catch containing BB in main referenced a non-existent
BB (one that has been moved into a separate function by
move_sese_region_to_fn).  But even in -fno-openmp C++ code I believe
there is no reason to have EH edges from cleanup regions accross
EH_FILTER_MUST_NOT_THROW regions out to some containing try .. catch.

Tested on x86_64-linux, ok for 4.3/4.2?

2007-04-24  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/30558
	* tree-eh.c (lower_eh_filter): If EH_FILTER_MUST_NOT_THROW
	clear this_state.prev_try.

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

--- gcc/tree-eh.c.jj	2007-03-12 17:18:17.000000000 +0100
+++ gcc/tree-eh.c	2007-04-24 17:32:16.000000000 +0200
@@ -1497,6 +1497,10 @@ lower_eh_filter (struct leh_state *state
 					 EH_FILTER_TYPES (inner));
   this_state = *state;
   this_state.cur_region = this_region;
+  /* For must not throw regions any cleanup regions inside it
+     can't reach outer catch regions.  */
+  if (EH_FILTER_MUST_NOT_THROW (inner))
+    this_state.prev_try = NULL;
 
   lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
 
--- gcc/testsuite/g++.dg/gomp/pr30558.C.jj	2007-04-24 17:41:47.000000000 +0200
+++ gcc/testsuite/g++.dg/gomp/pr30558.C	2007-04-24 17:42:24.000000000 +0200
@@ -0,0 +1,45 @@
+// PR tree-optimization/30558
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+static int s = 6;
+
+template <typename T> struct F
+{
+  ~F () {}
+  F (T x) {}
+  const T &operator[] (unsigned i) const { return s; }
+};
+
+template <typename T> F<T> foo (const F<T> &x)
+{
+  return F<T> (x[1]);
+}
+
+extern F<int> z;
+
+struct G
+{
+  G () { bar (2); }
+  F<int> &operator () (F<int> x) { return z; }
+  void bar (int);
+};
+
+int
+main ()
+{
+  try
+  {
+    G g;
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      {
+	F<int> j (i);
+	F<int> f = g (j);
+	F<int> h = foo (f);
+      }
+  }
+  catch (int &e)
+  {
+  }
+}

	Jakub


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