OSDN Git Service

2003-10-22 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / libsupc++ / eh_catch.cc
index ba49dfe..f8b7137 100644 (file)
@@ -1,20 +1,20 @@
 // -*- C++ -*- Exception handling routines for catching.
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2003 Free Software Foundation, Inc.
 //
-// This file is part of GNU CC.
+// This file is part of GCC.
 //
-// GNU CC is free software; you can redistribute it and/or modify
+// GCC is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either version 2, or (at your option)
 // any later version.
 //
-// GNU CC is distributed in the hope that it will be useful,
+// GCC is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 //
 // You should have received a copy of the GNU General Public License
-// along with GNU CC; see the file COPYING.  If not, write to
+// along with GCC; see the file COPYING.  If not, write to
 // the Free Software Foundation, 59 Temple Place - Suite 330,
 // Boston, MA 02111-1307, USA.
 
@@ -39,15 +39,28 @@ __cxa_begin_catch (void *exc_obj_in)
 {
   _Unwind_Exception *exceptionObject
     = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
-
-  // ??? Foreign exceptions can't be stacked here, and there doesn't
-  // appear to be any place to store for __cxa_end_catch to destroy.
-
-  __cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
   __cxa_eh_globals *globals = __cxa_get_globals ();
   __cxa_exception *prev = globals->caughtExceptions;
-  int count = header->handlerCount;
+  __cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
+
+  // Foreign exceptions can't be stacked here.  If the exception stack is
+  // empty, then fine.  Otherwise we really have no choice but to terminate.
+  // Note that this use of "header" is a lie.  It's fine so long as we only
+  // examine header->unwindHeader though.
+  if (header->unwindHeader.exception_class != __gxx_exception_class)
+    {
+      if (prev != 0)
+       std::terminate ();
+
+      // Remember for end_catch and rethrow.
+      globals->caughtExceptions = header;
+
+      // ??? No sensible value to return; we don't know what the 
+      // object is, much less where it is in relation to the header.
+      return 0;
+    }
 
+  int count = header->handlerCount;
   if (count < 0)
     // This exception was rethrown from an immediately enclosing region.
     count = -count + 1;
@@ -71,8 +84,22 @@ __cxa_end_catch ()
 {
   __cxa_eh_globals *globals = __cxa_get_globals_fast ();
   __cxa_exception *header = globals->caughtExceptions;
-  int count = header->handlerCount;
 
+  // A rethrow of a foreign exception will be removed from the
+  // the exception stack immediately by __cxa_rethrow.
+  if (!header)
+    return;
+
+  // A foreign exception couldn't have been stacked (see above),
+  // so by definition processing must be complete.
+  if (header->unwindHeader.exception_class != __gxx_exception_class)
+    {
+      globals->caughtExceptions = 0;
+      _Unwind_DeleteException (&header->unwindHeader);
+      return;
+    }
+
+  int count = header->handlerCount;
   if (count < 0)
     {
       // This exception was rethrown.  Decrement the (inverted) catch
@@ -92,7 +119,7 @@ __cxa_end_catch ()
     }
   else if (count < 0)
     // A bug in the exception handling library or compiler.
-    std::abort ();
+    std::terminate ();
 
   header->handlerCount = count;
 }