s390.c (s390_regs_ever_clobbered): Only save live eh regs for a function containing...
authorAndreas Krebbel <krebbel1@de.ibm.com>
Wed, 9 Nov 2005 11:42:38 +0000 (11:42 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 9 Nov 2005 11:42:38 +0000 (11:42 +0000)
2005-11-09  Andreas Krebbel  <krebbel1@de.ibm.com>

* config/s390/s390.c (s390_regs_ever_clobbered): Only save live eh regs
for a function containing a landing pad.
* testsuite/g++.dg/other/pr24623.C: Testcase added.

From-SVN: r106687

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/g++.dg/other/pr24623.C [new file with mode: 0644]

index eddcaa9..d5043a7 100644 (file)
@@ -1,5 +1,11 @@
 2005-11-09  Andreas Krebbel  <krebbel1@de.ibm.com>
 
+       * config/s390/s390.c (s390_regs_ever_clobbered): Only save live eh regs
+       for a function containing a landing pad.
+       * testsuite/g++.dg/other/pr24623.C: Testcase added.
+
+2005-11-09  Andreas Krebbel  <krebbel1@de.ibm.com>
+
        * flow.c (mark_set_1): Handle CLOBBERs like SETs if the register
        is live afterwards.
 
index cbb382d..75192e4 100644 (file)
@@ -6009,7 +6009,10 @@ s390_regs_ever_clobbered (int *regs_ever_clobbered)
      deal with this automatically.  */
   if (current_function_calls_eh_return || cfun->machine->has_landing_pad_p)
     for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
-      regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
+      if (current_function_calls_eh_return 
+         || (cfun->machine->has_landing_pad_p 
+             && regs_ever_live [EH_RETURN_DATA_REGNO (i)]))
+       regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
 
   /* For nonlocal gotos all call-saved registers have to be saved.
      This flag is also set for the unwinding code in libgcc.
diff --git a/gcc/testsuite/g++.dg/other/pr24623.C b/gcc/testsuite/g++.dg/other/pr24623.C
new file mode 100644 (file)
index 0000000..480bb39
--- /dev/null
@@ -0,0 +1,69 @@
+/* This used to ICE due to a backend problem on s390.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+class ReferenceCounted
+{
+public:
+
+  virtual ~ ReferenceCounted ()
+  {
+  }
+  void decrementRefCount () const
+  {
+    if (--const_cast < unsigned int &>(_ref_count) == 0)
+      {
+       delete this;
+      }
+  }
+  unsigned int _ref_count;
+};
+
+template < class T > class RefCountPointer
+{
+public:
+
+RefCountPointer (T * p = 0):_p (p)
+  {
+  }
+  RefCountPointer & operator= (const RefCountPointer < T > &o)
+  {
+    if (_p != o._p)
+      {
+       if (_p != 0)
+         _p->decrementRefCount ();
+      }
+  }
+  ~RefCountPointer ()
+  {
+  }
+  T *_p;
+};
+class Item:public ReferenceCounted
+{
+public:
+
+  typedef RefCountPointer < const Item > Ptr;
+};
+class AnyAtomicType:public Item
+{
+};
+class StaticContext
+{
+};
+class DynamicContext:public StaticContext
+{
+};
+class SortableItem
+{
+  SortableItem ();
+  int m_bAscending:1;
+  DynamicContext *m_context;
+    AnyAtomicType::Ptr m_item;
+};
+SortableItem::SortableItem ()
+{
+  m_context = __null;
+  m_item = __null;
+}