Commit 27abac26 by Gleb Natapov Committed by Jonathan Wakely

libstdc++/68297 avoid throw/catch in make_exception_ptr

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
parent 4c86ffcc
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> 2016-08-22 Jonathan Wakely <jwakely@redhat.com>
* doc/xml/api.xml: Replace hardcoded links for specific versions with * doc/xml/api.xml: Replace hardcoded links for specific versions with
......
...@@ -179,6 +179,7 @@ CXXABI_2.0 { ...@@ -179,6 +179,7 @@ CXXABI_2.0 {
__cxa_free_exception; __cxa_free_exception;
__cxa_free_dependent_exception; __cxa_free_dependent_exception;
__cxa_get_exception_ptr; __cxa_get_exception_ptr;
__cxa_init_primary_exception;
__cxa_get_globals; __cxa_get_globals;
__cxa_get_globals_fast; __cxa_get_globals_fast;
__cxa_guard_abort; __cxa_guard_abort;
...@@ -205,6 +206,7 @@ CXXABI_2.0 { ...@@ -205,6 +206,7 @@ CXXABI_2.0 {
# std::exception_ptr # std::exception_ptr
_ZNSt15__exception_ptr13exception_ptrC1Ev; _ZNSt15__exception_ptr13exception_ptrC1Ev;
_ZNSt15__exception_ptr13exception_ptrC2Ev; _ZNSt15__exception_ptr13exception_ptrC2Ev;
_ZNSt15__exception_ptr13exception_ptrC1EPv;
_ZNSt15__exception_ptr13exception_ptrC1ERKS0_; _ZNSt15__exception_ptr13exception_ptrC1ERKS0_;
_ZNSt15__exception_ptr13exception_ptrC2ERKS0_; _ZNSt15__exception_ptr13exception_ptrC2ERKS0_;
_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE; _ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE;
......
...@@ -2164,6 +2164,13 @@ CXXABI_1.3.10 { ...@@ -2164,6 +2164,13 @@ CXXABI_1.3.10 {
} CXXABI_1.3.9; } 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. # Symbols in the support library (libsupc++) supporting transactional memory.
CXXABI_TM_1 { CXXABI_TM_1 {
......
...@@ -205,6 +205,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++ ...@@ -205,6 +205,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++
bits_sup_headers = \ bits_sup_headers = \
${bits_sup_srcdir}/atomic_lockfree_defines.h \ ${bits_sup_srcdir}/atomic_lockfree_defines.h \
${bits_sup_srcdir}/cxxabi_forced.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_defines.h \
${bits_sup_srcdir}/exception_ptr.h \ ${bits_sup_srcdir}/exception_ptr.h \
${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/hash_bytes.h \
......
...@@ -495,6 +495,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++ ...@@ -495,6 +495,8 @@ bits_sup_srcdir = ${glibcxx_srcdir}/libsupc++
bits_sup_headers = \ bits_sup_headers = \
${bits_sup_srcdir}/atomic_lockfree_defines.h \ ${bits_sup_srcdir}/atomic_lockfree_defines.h \
${bits_sup_srcdir}/cxxabi_forced.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_defines.h \
${bits_sup_srcdir}/exception_ptr.h \ ${bits_sup_srcdir}/exception_ptr.h \
${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/hash_bytes.h \
......
...@@ -35,7 +35,7 @@ std_HEADERS = \ ...@@ -35,7 +35,7 @@ std_HEADERS = \
bits_HEADERS = \ bits_HEADERS = \
atomic_lockfree_defines.h cxxabi_forced.h \ 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) headers = $(std_HEADERS) $(bits_HEADERS)
......
...@@ -395,7 +395,7 @@ std_HEADERS = \ ...@@ -395,7 +395,7 @@ std_HEADERS = \
bits_HEADERS = \ bits_HEADERS = \
atomic_lockfree_defines.h cxxabi_forced.h \ 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) headers = $(std_HEADERS) $(bits_HEADERS)
@GLIBCXX_HOSTED_TRUE@c_sources = \ @GLIBCXX_HOSTED_TRUE@c_sources = \
......
...@@ -49,10 +49,7 @@ ...@@ -49,10 +49,7 @@
#include <bits/c++config.h> #include <bits/c++config.h>
#include <bits/cxxabi_tweaks.h> #include <bits/cxxabi_tweaks.h>
#include <bits/cxxabi_forced.h> #include <bits/cxxabi_forced.h>
#include <bits/cxxabi_init_exception.h>
#ifndef _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_CDTOR_CALLABI
#endif
#ifdef __cplusplus #ifdef __cplusplus
namespace __cxxabiv1 namespace __cxxabiv1
...@@ -608,10 +605,6 @@ namespace __cxxabiv1 ...@@ -608,10 +605,6 @@ namespace __cxxabiv1
__cxa_eh_globals* __cxa_eh_globals*
__cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__)); __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. // Free the space allocated for the primary exception.
void void
__cxa_free_exception(void*) _GLIBCXX_NOTHROW; __cxa_free_exception(void*) _GLIBCXX_NOTHROW;
......
// 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
...@@ -55,6 +55,22 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) ...@@ -55,6 +55,22 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
#endif #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 extern "C" void
__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
...@@ -64,17 +80,10 @@ __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 (); __cxa_eh_globals *globals = __cxa_get_globals ();
globals->uncaughtExceptions += 1; globals->uncaughtExceptions += 1;
// Definitely a primary. // Definitely a primary.
__cxa_refcounted_exception *header __cxa_refcounted_exception *header =
= __get_refcounted_exception_header_from_obj (obj); __cxa_init_primary_exception(obj, tinfo, dest);
header->referenceCount = 1; 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__ #ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException (&header->exc.unwindHeader); _Unwind_SjLj_RaiseException (&header->exc.unwindHeader);
......
...@@ -36,39 +36,12 @@ ...@@ -36,39 +36,12 @@
#include <bits/c++config.h> #include <bits/c++config.h>
#include <bits/atomic_lockfree_defines.h> #include <bits/atomic_lockfree_defines.h>
#include <bits/exception.h>
extern "C++" { extern "C++" {
namespace std 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 /** If an %exception is thrown which is not listed in a function's
* %exception specification, one of these may be thrown. */ * %exception specification, one of these may be thrown. */
class bad_exception : public exception class bad_exception : public exception
......
// 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
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include <bits/c++config.h> #include <bits/c++config.h>
#include <bits/exception_defines.h> #include <bits/exception_defines.h>
#include <bits/cxxabi_init_exception.h>
#include <typeinfo>
#include <new>
#if ATOMIC_INT_LOCK_FREE < 2 #if ATOMIC_INT_LOCK_FREE < 2
# error This platform does not support exception propagation. # error This platform does not support exception propagation.
...@@ -63,6 +66,9 @@ namespace std ...@@ -63,6 +66,9 @@ namespace std
*/ */
exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; 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. /// Throw the object pointed to by the exception_ptr.
void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
...@@ -87,6 +93,8 @@ namespace std ...@@ -87,6 +93,8 @@ namespace std
friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
friend void std::rethrow_exception(exception_ptr); friend void std::rethrow_exception(exception_ptr);
template<typename _Ex>
friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
public: public:
exception_ptr() _GLIBCXX_USE_NOEXCEPT; exception_ptr() _GLIBCXX_USE_NOEXCEPT;
...@@ -162,8 +170,12 @@ namespace std ...@@ -162,8 +170,12 @@ namespace std
swap(exception_ptr& __lhs, exception_ptr& __rhs) swap(exception_ptr& __lhs, exception_ptr& __rhs)
{ __lhs.swap(__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. /// Obtain an exception_ptr pointing to a copy of the supplied object.
template<typename _Ex> template<typename _Ex>
...@@ -173,7 +185,16 @@ namespace std ...@@ -173,7 +185,16 @@ namespace std
#if __cpp_exceptions #if __cpp_exceptions
try 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(...) catch(...)
{ {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#pragma GCC system_header #pragma GCC system_header
#include <exception> #include <bits/exception.h>
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#include <bits/hash_bytes.h> #include <bits/hash_bytes.h>
#endif #endif
......
...@@ -216,6 +216,7 @@ check_version(symbol& test, bool added) ...@@ -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.8");
known_versions.push_back("CXXABI_1.3.9"); known_versions.push_back("CXXABI_1.3.9");
known_versions.push_back("CXXABI_1.3.10"); 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_TM_1");
known_versions.push_back("CXXABI_FLOAT128"); known_versions.push_back("CXXABI_FLOAT128");
} }
...@@ -234,7 +235,7 @@ check_version(symbol& test, bool added) ...@@ -234,7 +235,7 @@ check_version(symbol& test, bool added)
// Check that added symbols are added in the latest pre-release version. // Check that added symbols are added in the latest pre-release version.
bool latestp = (test.version_name == "GLIBCXX_3.4.23" 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_FLOAT128"
|| test.version_name == "CXXABI_TM_1"); || test.version_name == "CXXABI_TM_1");
if (added && !latestp) if (added && !latestp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment