PR libstdc++/59392: Fix ARM EABI uncaught throw from unexpected exception handler
authorRoland McGrath <mcgrathr@google.com>
Wed, 12 Mar 2014 22:42:13 +0000 (22:42 +0000)
committerRoland McGrath <roland@gcc.gnu.org>
Wed, 12 Mar 2014 22:42:13 +0000 (22:42 +0000)
libstdc++-v3/
PR libstdc++/59392
* libsupc++/eh_call.cc (__cxa_call_unexpected): Call __do_catch with
the address of a null pointer, not with a null pointer to pointer.
Copy comment for this case from eh_personality.cc:__cxa_call_unexpected.
* testsuite/18_support/bad_exception/59392.cc: New file.

Co-Authored-By: Mark Seaborn <mseaborn@google.com>
From-SVN: r208519

libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/eh_call.cc
libstdc++-v3/testsuite/18_support/bad_exception/59392.cc [new file with mode: 0644]

index 7c92019a8afa6a81c14366de130808fae69bb8b5..720ef1dc4c112c3dc972f8f1d28024545c40de14 100644 (file)
@@ -1,3 +1,12 @@
+2014-03-12  Roland McGrath  <mcgrathr@google.com>
+           Mark Seaborn  <mseaborn@google.com>
+
+       PR libstdc++/59392
+       * libsupc++/eh_call.cc (__cxa_call_unexpected): Call __do_catch with
+       the address of a null pointer, not with a null pointer to pointer.
+       Copy comment for this case from eh_personality.cc:__cxa_call_unexpected.
+       * testsuite/18_support/bad_exception/59392.cc: New file.
+
 2014-03-11  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/60499
index dc32dd392e843c939ff9c16d0be5f41b4ad736ed..76776927aeef48238dcbbf30d62d0e4e5631155e 100644 (file)
@@ -104,14 +104,14 @@ __cxa_call_unexpected(void* exc_obj_in)
   } end_catch_protect_obj;
 
 
-  __try 
-    { 
+  __try
+    {
       if (foreign_exception)
        std::unexpected();
       else
        __unexpected(unexpectedHandler);
     }
-  __catch(...) 
+  __catch(...)
     {
       /* See if the new exception matches the rtti list.  */
       if (foreign_exception)
@@ -140,15 +140,19 @@ __cxa_call_unexpected(void* exc_obj_in)
                               &new_ptr) != ctm_failed)
            __throw_exception_again;
 
-         if (catch_type->__do_catch(&bad_exc, 0, 1))
+         // If the exception spec allows std::bad_exception, throw that.
+         // We don't have a thrown object to compare against, but since
+         // bad_exception doesn't have virtual bases, that's OK; just pass NULL.
+         void* obj = NULL;
+         if (catch_type->__do_catch(&bad_exc, &obj, 1))
            bad_exception_allowed = true;
        }
 
       // If the exception spec allows std::bad_exception, throw that.
-#ifdef __EXCEPTIONS  
+#ifdef __EXCEPTIONS
       if (bad_exception_allowed)
        throw std::bad_exception();
-#endif   
+#endif
 
       // Otherwise, die.
       __terminate(terminateHandler);
diff --git a/libstdc++-v3/testsuite/18_support/bad_exception/59392.cc b/libstdc++-v3/testsuite/18_support/bad_exception/59392.cc
new file mode 100644 (file)
index 0000000..c9b65a2
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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 3, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <cstdlib>
+
+class expected {};
+class unexpected {};
+class from_handler {};
+
+static void func_with_exception_spec() throw(expected)
+{
+  throw unexpected();
+}
+
+static void unexpected_handler()
+{
+  throw from_handler();
+}
+
+static void terminate_handler()
+{
+  exit(0);
+}
+
+// libstdc++/59392
+int main()
+{
+  std::set_unexpected(unexpected_handler);
+  std::set_terminate(terminate_handler);
+  try {
+    func_with_exception_spec();
+  } catch (expected&) {
+    abort();
+  }
+  abort();
+}