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
This commit is contained in:
Gleb Natapov 2016-08-22 17:29:31 +00:00 committed by Jonathan Wakely
parent 4c86ffccf9
commit 27abac2648
15 changed files with 243 additions and 51 deletions

View 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

View 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;

View 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 {

View 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 \

View 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 \

View 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)

View 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 = \

View file

@ -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;

View file

@ -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

View 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);

View file

@ -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

View file

@ -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

View 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
{
#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(...)
{

View file

@ -31,7 +31,7 @@
#pragma GCC system_header
#include <exception>
#include <bits/exception.h>
#if __cplusplus >= 201103L
#include <bits/hash_bytes.h>
#endif

View 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)