On 21/08/16 15:20 +0300, Gleb Natapov wrote:
Jonathan,
Is this version OK with you?
I've committed the attached version, which just adds some whitespace
and fixes the testsuite_abi.cc test.
Thanks very much for the improvement to the code.
commit f80c0cc401fc34b424662286bedc559d0e2bb243
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Mon Aug 22 18:03:39 2016 +0100
libstdc++/68297 avoid throw/catch in make_exception_ptr
2016-08-22 Gleb Natapov <g...@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.
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 8304dee..65866a3 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -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;
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index b7f54e2..f51c6f9 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -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 {
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 0a10994..9cd18df 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -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 \
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index b45b5ae..ba4eac1 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -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)
diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h
index 11ff9e5..f4b8f75 100644
--- a/libstdc++-v3/libsupc++/cxxabi.h
+++ b/libstdc++-v3/libsupc++/cxxabi.h
@@ -49,10 +49,7 @@
#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
index 0000000..9af7625
--- /dev/null
+++ b/libstdc++-v3/libsupc++/cxxabi_init_exception.h
@@ -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
diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc
index 9aac218..a05f4eb 100644
--- a/libstdc++-v3/libsupc++/eh_throw.cc
+++ b/libstdc++-v3/libsupc++/eh_throw.cc
@@ -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);
diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception
index 63631f6..8be903b 100644
--- a/libstdc++-v3/libsupc++/exception
+++ b/libstdc++-v3/libsupc++/exception
@@ -36,39 +36,12 @@
#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
index 0000000..09ac4e0
--- /dev/null
+++ b/libstdc++-v3/libsupc++/exception.h
@@ -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
diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h
index 783e539..21e4e8b 100644
--- a/libstdc++-v3/libsupc++/exception_ptr.h
+++ b/libstdc++-v3/libsupc++/exception_ptr.h
@@ -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(...)
{
diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo
index baedf01..1c5ccc5 100644
--- a/libstdc++-v3/libsupc++/typeinfo
+++ b/libstdc++-v3/libsupc++/typeinfo
@@ -31,7 +31,7 @@
#pragma GCC system_header
-#include <exception>
+#include <bits/exception.h>
#if __cplusplus >= 201103L
#include <bits/hash_bytes.h>
#endif
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 9001345..5174a7f 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -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)