libstdc++/68297 avoid throw/catch in make_exception_ptr
authorGleb Natapov <gleb@scylladb.com>
Mon, 22 Aug 2016 17:29:31 +0000 (17:29 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 22 Aug 2016 17:29:31 +0000 (18:29 +0100)
2016-08-22  Gleb Natapov  <gleb@scylladb.com>

PR libstdc++/68297
* config/abi/pre/gnu-versioned-namespace.ver: Export
__cxa_init_primary_exception and std::exception_ptr(void*).
* config/abi/pre/gnu.ver (CXXABI_1.3.11) : Add new symbol version and
export __cxa_init_primary_exception and std::exception_ptr(void*).
* include/Makefile.am: Add new headers.
* include/Makefile.in: Regenerate.
* libsupc++/Makefile.am: Add new headers.
* libsupc++/Makefile.in: Regenerate.
* libsupc++/cxxabi.h (__cxa_allocate_exception): Move to ...
* libsupc++/cxxabi_init_exception.h: New header.
(__cxa_init_primary_exception): Declare.
* libsupc++/eh_throw.cc (__cxa_init_primary_exception): Define.
(__cxa_throw): Use __cxa_init_primary_exception.
* libsupc++/exception (std::exception): Move to ...
* libsupc++/exception.h: New header.
* libsupc++/exception_ptr.h (__exception_ptr::exception_ptr): Add
friend declaration.
(__exception_ptr::__dest_thunk): New function template.
(std::make_exception_ptr) [__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]:
Use __cxa_allocate_exception and __cxa_init_primary_exception to
create exception_ptr.
* libsupc++/typeinfo: Include bits/exception.h instead of exception.
* testsuite/util/testsuite_abi.cc: Add CXXABI_1.3.11 version.

From-SVN: r239664

15 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/libsupc++/Makefile.am
libstdc++-v3/libsupc++/Makefile.in
libstdc++-v3/libsupc++/cxxabi.h
libstdc++-v3/libsupc++/cxxabi_init_exception.h [new file with mode: 0644]
libstdc++-v3/libsupc++/eh_throw.cc
libstdc++-v3/libsupc++/exception
libstdc++-v3/libsupc++/exception.h [new file with mode: 0644]
libstdc++-v3/libsupc++/exception_ptr.h
libstdc++-v3/libsupc++/typeinfo
libstdc++-v3/testsuite/util/testsuite_abi.cc

index 33b884099b1c1f519370f99b5c56e5b0681c95e2..299bce642e8c925208e039d2f29ca7f9ae695379 100644 (file)
@@ -1,3 +1,30 @@
+2016-08-22  Gleb Natapov  <gleb@scylladb.com>
+
+       PR libstdc++/68297
+       * config/abi/pre/gnu-versioned-namespace.ver: Export
+       __cxa_init_primary_exception and std::exception_ptr(void*).
+       * config/abi/pre/gnu.ver (CXXABI_1.3.11) : Add new symbol version and
+       export __cxa_init_primary_exception and std::exception_ptr(void*).
+       * include/Makefile.am: Add new headers.
+       * include/Makefile.in: Regenerate.
+       * libsupc++/Makefile.am: Add new headers.
+       * libsupc++/Makefile.in: Regenerate.
+       * libsupc++/cxxabi.h (__cxa_allocate_exception): Move to ...
+       * libsupc++/cxxabi_init_exception.h: New header.
+       (__cxa_init_primary_exception): Declare.
+       * libsupc++/eh_throw.cc (__cxa_init_primary_exception): Define.
+       (__cxa_throw): Use __cxa_init_primary_exception.
+       * libsupc++/exception (std::exception): Move to ...
+       * libsupc++/exception.h: New header.
+       * libsupc++/exception_ptr.h (__exception_ptr::exception_ptr): Add
+       friend declaration.
+       (__exception_ptr::__dest_thunk): New function template.
+       (std::make_exception_ptr) [__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]:
+       Use __cxa_allocate_exception and __cxa_init_primary_exception to
+       create exception_ptr.
+       * libsupc++/typeinfo: Include bits/exception.h instead of exception.
+       * testsuite/util/testsuite_abi.cc: Add CXXABI_1.3.11 version.
+
 2016-08-22  Jonathan Wakely  <jwakely@redhat.com>
 
        * doc/xml/api.xml: Replace hardcoded links for specific versions with
index 8304dee089c99514c792de63bfb8fbf452f39d75..65866a380f3b3b0eabfdc11100a14843ea3c27fa 100644 (file)
@@ -179,6 +179,7 @@ CXXABI_2.0 {
     __cxa_free_exception;
     __cxa_free_dependent_exception;
     __cxa_get_exception_ptr;
+    __cxa_init_primary_exception;
     __cxa_get_globals;
     __cxa_get_globals_fast;
     __cxa_guard_abort;
@@ -205,6 +206,7 @@ CXXABI_2.0 {
     # std::exception_ptr
     _ZNSt15__exception_ptr13exception_ptrC1Ev;
     _ZNSt15__exception_ptr13exception_ptrC2Ev;
+    _ZNSt15__exception_ptr13exception_ptrC1EPv;
     _ZNSt15__exception_ptr13exception_ptrC1ERKS0_;
     _ZNSt15__exception_ptr13exception_ptrC2ERKS0_;
     _ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE;
index b7f54e2ae344091f8262d88f817307b9eca4e80a..f51c6f961b08728bc846e9a44effa5173239306d 100644 (file)
@@ -2164,6 +2164,13 @@ CXXABI_1.3.10 {
 
 } CXXABI_1.3.9;
 
+CXXABI_1.3.11 {
+
+    __cxa_init_primary_exception;
+    _ZNSt15__exception_ptr13exception_ptrC1EPv;
+
+} CXXABI_1.3.10;
+
 # Symbols in the support library (libsupc++) supporting transactional memory.
 CXXABI_TM_1 {
 
index 0a10994de4e5c762e1b69ced04ef82a4ae2d7cb0..9cd18dfa3b9c15474a943a24e676bd8cc2ed8dff 100644 (file)
@@ -205,6 +205,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++
 bits_sup_headers = \
        ${bits_sup_srcdir}/atomic_lockfree_defines.h \
        ${bits_sup_srcdir}/cxxabi_forced.h \
+       ${bits_sup_srcdir}/cxxabi_init_exception.h \
+       ${bits_sup_srcdir}/exception.h \
        ${bits_sup_srcdir}/exception_defines.h \
        ${bits_sup_srcdir}/exception_ptr.h \
        ${bits_sup_srcdir}/hash_bytes.h \
index 8b774a98f7bbf39023a99f1d2f931cf1519e2642..d799860d095d6768cd2a9a7070d4f899981ed4ee 100644 (file)
@@ -495,6 +495,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++
 bits_sup_headers = \
        ${bits_sup_srcdir}/atomic_lockfree_defines.h \
        ${bits_sup_srcdir}/cxxabi_forced.h \
+       ${bits_sup_srcdir}/cxxabi_init_exception.h \
+       ${bits_sup_srcdir}/exception.h \
        ${bits_sup_srcdir}/exception_defines.h \
        ${bits_sup_srcdir}/exception_ptr.h \
        ${bits_sup_srcdir}/hash_bytes.h \
index b45b5ae2eb52b93b8f70ecb8dafd59b95574e99c..ba4eac1e3f86670f15defa509a65c5f76316d7f3 100644 (file)
@@ -35,7 +35,7 @@ std_HEADERS = \
 
 bits_HEADERS = \
        atomic_lockfree_defines.h cxxabi_forced.h \
-       exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
+       exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h exception.h cxxabi_init_exception.h
 
 headers = $(std_HEADERS) $(bits_HEADERS)
 
index f3648ac475c374c30fae165a2c1f9214a52e7d13..3fb9d16e527ff046a89d6c8730981a2b5b47b12d 100644 (file)
@@ -395,7 +395,7 @@ std_HEADERS = \
 
 bits_HEADERS = \
        atomic_lockfree_defines.h cxxabi_forced.h \
-       exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
+       exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h exception.h cxxabi_init_exception.h
 
 headers = $(std_HEADERS) $(bits_HEADERS)
 @GLIBCXX_HOSTED_TRUE@c_sources = \
index 11ff9e568de611328bd58989ce02e0b8a4e643ab..f4b8f75fd18015a668f73b8e00a41755e5d1007a 100644 (file)
 #include <bits/c++config.h>
 #include <bits/cxxabi_tweaks.h>
 #include <bits/cxxabi_forced.h>
-
-#ifndef _GLIBCXX_CDTOR_CALLABI
-#define _GLIBCXX_CDTOR_CALLABI
-#endif
+#include <bits/cxxabi_init_exception.h>
 
 #ifdef __cplusplus
 namespace __cxxabiv1
@@ -608,10 +605,6 @@ namespace __cxxabiv1
   __cxa_eh_globals*
   __cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__));
 
-  // Allocate memory for the primary exception plus the thrown object.
-  void*
-  __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
-
   // Free the space allocated for the primary exception.
   void 
   __cxa_free_exception(void*) _GLIBCXX_NOTHROW;
diff --git a/libstdc++-v3/libsupc++/cxxabi_init_exception.h b/libstdc++-v3/libsupc++/cxxabi_init_exception.h
new file mode 100644 (file)
index 0000000..9af7625
--- /dev/null
@@ -0,0 +1,77 @@
+// ABI Support -*- C++ -*-
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// 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 3, or (at your option)
+// any later version.
+//
+// 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.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/cxxabi_init_exception.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly.
+ */
+
+#ifndef _CXXABI_INIT_EXCEPTION_H
+#define _CXXABI_INIT_EXCEPTION_H 1
+
+#pragma GCC system_header
+
+#pragma GCC visibility push(default)
+
+#include <stddef.h>
+#include <bits/c++config.h>
+
+#ifndef _GLIBCXX_CDTOR_CALLABI
+#define _GLIBCXX_CDTOR_CALLABI
+#define _GLIBCXX_HAVE_CDTOR_CALLABI 0
+#else
+#define _GLIBCXX_HAVE_CDTOR_CALLABI 1
+#endif
+
+#ifdef __cplusplus
+
+namespace std
+{
+  class type_info;
+}
+
+namespace __cxxabiv1
+{
+  struct __cxa_refcounted_exception;
+
+  extern "C"
+    {
+      // Allocate memory for the primary exception plus the thrown object.
+      void*
+      __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
+
+      // Initialize exception (this is a GNU extension)
+      __cxa_refcounted_exception*
+      __cxa_init_primary_exception(void *object, std::type_info *tinfo,
+                void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) _GLIBCXX_NOTHROW;
+
+    }
+} // namespace __cxxabiv1
+
+#endif
+
+#pragma GCC visibility pop
+
+#endif // _CXXABI_INIT_EXCEPTION_H
index 9aac218527c2a5a8091d8890eec7472932101006..a05f4eb04ea102580464b2020ed95e1ad5e9a663 100644 (file)
@@ -55,6 +55,22 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
 #endif
 }
 
+extern "C" __cxa_refcounted_exception*
+__cxxabiv1::__cxa_init_primary_exception(void *obj, std::type_info *tinfo,
+                                         void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
+{
+  __cxa_refcounted_exception *header
+    = __get_refcounted_exception_header_from_obj (obj);
+  header->referenceCount = 0;
+  header->exc.exceptionType = tinfo;
+  header->exc.exceptionDestructor = dest;
+  header->exc.unexpectedHandler = std::get_unexpected ();
+  header->exc.terminateHandler = std::get_terminate ();
+  __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
+  header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;
+
+  return header;
+}
 
 extern "C" void
 __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
@@ -64,17 +80,10 @@ __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
 
   __cxa_eh_globals *globals = __cxa_get_globals ();
   globals->uncaughtExceptions += 1;
-
   // Definitely a primary.
-  __cxa_refcounted_exception *header
-    = __get_refcounted_exception_header_from_obj (obj);
+  __cxa_refcounted_exception *header =
+    __cxa_init_primary_exception(obj, tinfo, dest);
   header->referenceCount = 1;
-  header->exc.exceptionType = tinfo;
-  header->exc.exceptionDestructor = dest;
-  header->exc.unexpectedHandler = std::get_unexpected ();
-  header->exc.terminateHandler = std::get_terminate ();
-  __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
-  header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;
 
 #ifdef __USING_SJLJ_EXCEPTIONS__
   _Unwind_SjLj_RaiseException (&header->exc.unwindHeader);
index 63631f6d1d125fc5d599d317753001070318906d..8be903ba2dbadc8eb7ad328d5c6edb1ef751eb8c 100644 (file)
 
 #include <bits/c++config.h>
 #include <bits/atomic_lockfree_defines.h>
+#include <bits/exception.h>
 
 extern "C++" {
 
 namespace std
 {
-  /**
-   * @defgroup exceptions Exceptions
-   * @ingroup diagnostics
-   *
-   * Classes and functions for reporting errors via exception classes.
-   * @{
-   */
-
-  /**
-   *  @brief Base class for all library exceptions.
-   *
-   *  This is the base class for all exceptions thrown by the standard
-   *  library, and by certain language expressions.  You are free to derive
-   *  your own %exception classes, or use a different hierarchy, or to
-   *  throw non-class data (e.g., fundamental types).
-   */
-  class exception
-  {
-  public:
-    exception() _GLIBCXX_USE_NOEXCEPT { }
-    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
-
-    /** Returns a C-style character string describing the general cause
-     *  of the current error.  */
-    virtual const char*
-    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
-  };
-
   /** If an %exception is thrown which is not listed in a function's
    *  %exception specification, one of these may be thrown.  */
   class bad_exception : public exception
diff --git a/libstdc++-v3/libsupc++/exception.h b/libstdc++-v3/libsupc++/exception.h
new file mode 100644 (file)
index 0000000..09ac4e0
--- /dev/null
@@ -0,0 +1,78 @@
+// Exception Handling support header for -*- C++ -*-
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// 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 3, or (at your option)
+// any later version.
+//
+// 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.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/exception.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly.
+ */
+
+#ifndef __EXCEPTION_H
+#define __EXCEPTION_H 1
+
+#pragma GCC system_header
+
+#pragma GCC visibility push(default)
+
+#include <bits/c++config.h>
+
+extern "C++" {
+
+namespace std
+{
+  /**
+   * @defgroup exceptions Exceptions
+   * @ingroup diagnostics
+   *
+   * Classes and functions for reporting errors via exception classes.
+   * @{
+   */
+
+  /**
+   *  @brief Base class for all library exceptions.
+   *
+   *  This is the base class for all exceptions thrown by the standard
+   *  library, and by certain language expressions.  You are free to derive
+   *  your own %exception classes, or use a different hierarchy, or to
+   *  throw non-class data (e.g., fundamental types).
+   */
+  class exception
+  {
+  public:
+    exception() _GLIBCXX_USE_NOEXCEPT { }
+    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+
+    /** Returns a C-style character string describing the general cause
+     *  of the current error.  */
+    virtual const char*
+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+  };
+
+} // namespace std
+
+}
+
+#pragma GCC visibility pop
+
+#endif
index 783e5397642a5e8bd02ff2e2e26f7a94baa53818..21e4e8b834858163d25ea835e511d587d1bfe9d1 100644 (file)
@@ -35,6 +35,9 @@
 
 #include <bits/c++config.h>
 #include <bits/exception_defines.h>
+#include <bits/cxxabi_init_exception.h>
+#include <typeinfo>
+#include <new>
 
 #if ATOMIC_INT_LOCK_FREE < 2
 #  error This platform does not support exception propagation.
@@ -63,6 +66,9 @@ namespace std
    */
   exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT;
 
+  template<typename _Ex>
+  exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
+
   /// Throw the object pointed to by the exception_ptr.
   void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
 
@@ -87,6 +93,8 @@ namespace std
 
       friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
       friend void std::rethrow_exception(exception_ptr);
+      template<typename _Ex>
+      friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
 
     public:
       exception_ptr() _GLIBCXX_USE_NOEXCEPT;
@@ -162,8 +170,12 @@ namespace std
     swap(exception_ptr& __lhs, exception_ptr& __rhs)
     { __lhs.swap(__rhs); }
 
-  } // namespace __exception_ptr
+    template<typename _Ex>
+      inline void
+      __dest_thunk(void* x)
+      { static_cast<_Ex*>(x)->~_Ex(); }
 
+  } // namespace __exception_ptr
 
   /// Obtain an exception_ptr pointing to a copy of the supplied object.
   template<typename _Ex>
@@ -173,7 +185,16 @@ namespace std
 #if __cpp_exceptions
       try
        {
-         throw __ex;
+#if __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI
+          void *__e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
+          (void)__cxxabiv1::__cxa_init_primary_exception(__e,
+                                           const_cast<std::type_info*>(&typeid(__ex)),
+                                           __exception_ptr::__dest_thunk<_Ex>);
+          new (__e) _Ex(__ex);
+          return exception_ptr(__e);
+#else
+          throw __ex;
+#endif
        }
       catch(...)
        {
index baedf010214dce38cb6e7b19e6825096763d02f2..1c5ccc5ad5d96bea23e90f489332a501092a4515 100644 (file)
@@ -31,7 +31,7 @@
 
 #pragma GCC system_header
 
-#include <exception>
+#include <bits/exception.h>
 #if __cplusplus >= 201103L
 #include <bits/hash_bytes.h>
 #endif
index 90013454ba901dbdf07575beb202ff0989df9de8..5174a7f0d9340044b175ba4a5381a7a7f000423e 100644 (file)
@@ -216,6 +216,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("CXXABI_1.3.8");
       known_versions.push_back("CXXABI_1.3.9");
       known_versions.push_back("CXXABI_1.3.10");
+      known_versions.push_back("CXXABI_1.3.11");
       known_versions.push_back("CXXABI_TM_1");
       known_versions.push_back("CXXABI_FLOAT128");
     }
@@ -234,7 +235,7 @@ check_version(symbol& test, bool added)
 
       // Check that added symbols are added in the latest pre-release version.
       bool latestp = (test.version_name == "GLIBCXX_3.4.23"
-                    || test.version_name == "CXXABI_1.3.10"
+                    || test.version_name == "CXXABI_1.3.11"
                     || test.version_name == "CXXABI_FLOAT128"
                     || test.version_name == "CXXABI_TM_1");
       if (added && !latestp)