Commit 3941b260 by Jonathan Wakely Committed by Jonathan Wakely

re PR libstdc++/60612 (Throwing exception, catching and rethrowing…

re PR libstdc++/60612 (Throwing exception, catching and rethrowing (std::exception_ptr) in destructor leads to segfault)

	PR libstdc++/60612
	* libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is
	compatible with __cxa_exception.
	* libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding.
	Fix typos in comments.
	* testsuite/18_support/exception_ptr/60612-terminate.cc: New.
	* testsuite/18_support/exception_ptr/60612-unexpected.cc: New.

From-SVN: r208871
parent 324dc401
2014-03-27 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/60612
* libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is
compatible with __cxa_exception.
* libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding.
Fix typos in comments.
* testsuite/18_support/exception_ptr/60612-terminate.cc: New.
* testsuite/18_support/exception_ptr/60612-unexpected.cc: New.
2014-03-25 Jonathan Wakely <jwakely@redhat.com> 2014-03-25 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/60658 PR libstdc++/60658
......
...@@ -35,6 +35,32 @@ ...@@ -35,6 +35,32 @@
using namespace __cxxabiv1; using namespace __cxxabiv1;
// Verify assumptions about member layout in exception types
namespace
{
template<typename Ex>
constexpr std::size_t unwindhdr()
{ return offsetof(Ex, unwindHeader); }
template<typename Ex>
constexpr std::size_t termHandler()
{ return unwindhdr<Ex>() - offsetof(Ex, terminateHandler); }
static_assert( termHandler<__cxa_exception>()
== termHandler<__cxa_dependent_exception>(),
"__cxa_dependent_exception::termHandler layout is correct" );
#ifndef __ARM_EABI_UNWINDER__
template<typename Ex>
constexpr std::ptrdiff_t adjptr()
{ return unwindhdr<Ex>() - offsetof(Ex, adjustedPtr); }
static_assert( adjptr<__cxa_exception>()
== adjptr<__cxa_dependent_exception>(),
"__cxa_dependent_exception::adjustedPtr layout is correct" );
#endif
}
std::__exception_ptr::exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT std::__exception_ptr::exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT
: _M_exception_object(0) { } : _M_exception_object(0) { }
......
...@@ -81,7 +81,7 @@ struct __cxa_exception ...@@ -81,7 +81,7 @@ struct __cxa_exception
// Stack of exceptions in cleanups. // Stack of exceptions in cleanups.
__cxa_exception* nextPropagatingException; __cxa_exception* nextPropagatingException;
// The nuber of active cleanup handlers for this exception. // The number of active cleanup handlers for this exception.
int propagationCount; int propagationCount;
#else #else
// Cache parsed handler data from the personality routine Phase 1 // Cache parsed handler data from the personality routine Phase 1
...@@ -114,6 +114,11 @@ struct __cxa_dependent_exception ...@@ -114,6 +114,11 @@ struct __cxa_dependent_exception
// The primary exception this thing depends on. // The primary exception this thing depends on.
void *primaryException; void *primaryException;
// Unused member to get similar layout to __cxa_exception, otherwise the
// alignment requirements of _Unwind_Exception would require padding bytes
// before the unwindHeader member.
void (_GLIBCXX_CDTOR_CALLABI *__padding)(void *);
// The C++ standard has entertaining rules wrt calling set_terminate // The C++ standard has entertaining rules wrt calling set_terminate
// and set_unexpected in the middle of the exception cleanup process. // and set_unexpected in the middle of the exception cleanup process.
std::unexpected_handler unexpectedHandler; std::unexpected_handler unexpectedHandler;
...@@ -130,7 +135,7 @@ struct __cxa_dependent_exception ...@@ -130,7 +135,7 @@ struct __cxa_dependent_exception
// Stack of exceptions in cleanups. // Stack of exceptions in cleanups.
__cxa_exception* nextPropagatingException; __cxa_exception* nextPropagatingException;
// The nuber of active cleanup handlers for this exception. // The number of active cleanup handlers for this exception.
int propagationCount; int propagationCount;
#else #else
// Cache parsed handler data from the personality routine Phase 1 // Cache parsed handler data from the personality routine Phase 1
......
// { dg-options "-std=gnu++11" }
// { dg-require-atomic-builtins "" }
// 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/>.
// PR libstdc++/60612
#include <exception>
#include <stdlib.h>
void terminate() { _Exit(0); }
void f() noexcept
{
try {
throw 1;
} catch (...) {
std::set_terminate(terminate);
std::rethrow_exception(std::current_exception());
}
}
int main()
{
f();
}
// { dg-options "-std=gnu++11" }
// { dg-require-atomic-builtins "" }
// 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/>.
// PR libstdc++/60612
#include <exception>
#include <stdlib.h>
void unexpected() { _Exit(0); }
void f() throw()
{
try {
throw 1;
} catch (...) {
std::set_unexpected(unexpected);
std::rethrow_exception(std::current_exception());
}
}
int main()
{
f();
}
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