Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 May 2016 22:09:44 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r299140 - vendor/libcxxrt/dist
Message-ID:  <201605052209.u45M9i0D087623@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu May  5 22:09:43 2016
New Revision: 299140
URL: https://svnweb.freebsd.org/changeset/base/299140

Log:
  Import libcxxrt master 516a65c109eb0a01e5e95fbef455eb3215135cef.
  
  Interesting fixes:
  760ae47 Add std::uncaught_exceptions().
  e45e6db Fix off-by-ones in emergency exception buffer free
  3adaa2e Fix _Unwind_Exception cleanup functions
  286776c Check exception cleanup function ptr before calling
  edda626 Correct exception specifications on new and delete operators

Modified:
  vendor/libcxxrt/dist/exception.cc
  vendor/libcxxrt/dist/memory.cc

Modified: vendor/libcxxrt/dist/exception.cc
==============================================================================
--- vendor/libcxxrt/dist/exception.cc	Thu May  5 21:25:41 2016	(r299139)
+++ vendor/libcxxrt/dist/exception.cc	Thu May  5 22:09:43 2016	(r299140)
@@ -304,13 +304,17 @@ static pthread_key_t eh_key;
 static void exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
-	__cxa_free_exception(static_cast<void*>(ex));
+	// Exception layout:
+	// [__cxa_exception [_Unwind_Exception]] [exception object]
+	//
+	// __cxa_free_exception expects a pointer to the exception object
+	__cxa_free_exception(static_cast<void*>(ex + 1));
 }
 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
 
-	__cxa_free_dependent_exception(static_cast<void*>(ex));
+	__cxa_free_dependent_exception(static_cast<void*>(ex + 1));
 }
 
 /**
@@ -340,7 +344,8 @@ static void thread_cleanup(void* thread_
 		if (info->foreign_exception_state != __cxa_thread_info::none)
 		{
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions);
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+			if (e->exception_cleanup)
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
 		}
 		else
 		{
@@ -516,7 +521,7 @@ static void emergency_malloc_free(char *
 			break;
 		}
 	}
-	assert(buffer > 0 &&
+	assert(buffer >= 0 &&
 	       "Trying to free something that is not an emergency buffer!");
 	// emergency_malloc() is expected to return 0-initialized data.  We don't
 	// zero the buffer when allocating it, because the static buffers will
@@ -556,7 +561,7 @@ static void free_exception(char *e)
 {
 	// If this allocation is within the address range of the emergency buffer,
 	// don't call free() because it was not allocated with malloc()
-	if ((e > emergency_buffer) &&
+	if ((e >= emergency_buffer) &&
 	    (e < (emergency_buffer + sizeof(emergency_buffer))))
 	{
 		emergency_malloc_free(e);
@@ -1280,12 +1285,13 @@ extern "C" void __cxa_end_catch()
 	
 	if (ti->foreign_exception_state != __cxa_thread_info::none)
 	{
-		globals->caughtExceptions = 0;
 		if (ti->foreign_exception_state != __cxa_thread_info::rethrown)
 		{
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions);
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+			if (e->exception_cleanup)
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
 		}
+		globals->caughtExceptions = 0;
 		ti->foreign_exception_state = __cxa_thread_info::none;
 		return;
 	}
@@ -1472,6 +1478,15 @@ namespace std
 		return info->globals.uncaughtExceptions != 0;
 	}
 	/**
+	 * Returns the number of exceptions currently being thrown that have not
+	 * been caught.  This can occur inside a nested catch statement.
+	 */
+	int uncaught_exceptions() throw()
+	{
+		__cxa_thread_info *info = thread_info();
+		return info->globals.uncaughtExceptions;
+	}
+	/**
 	 * Returns the current unexpected handler.
 	 */
 	unexpected_handler get_unexpected() throw()

Modified: vendor/libcxxrt/dist/memory.cc
==============================================================================
--- vendor/libcxxrt/dist/memory.cc	Thu May  5 21:25:41 2016	(r299139)
+++ vendor/libcxxrt/dist/memory.cc	Thu May  5 22:09:43 2016	(r299140)
@@ -71,8 +71,17 @@ namespace std
 }
 
 
+#if __cplusplus < 201103L
+#define NOEXCEPT throw()
+#define BADALLOC throw(std::bad_alloc)
+#else
+#define NOEXCEPT noexcept
+#define BADALLOC
+#endif
+
+
 __attribute__((weak))
-void* operator new(size_t size)
+void* operator new(size_t size) BADALLOC
 {
 	if (0 == size)
 	{
@@ -97,7 +106,7 @@ void* operator new(size_t size)
 }
 
 __attribute__((weak))
-void* operator new(size_t size, const std::nothrow_t &) throw()
+void* operator new(size_t size, const std::nothrow_t &) NOEXCEPT
 {
 	try {
 		return :: operator new(size);
@@ -110,27 +119,21 @@ void* operator new(size_t size, const st
 
 
 __attribute__((weak))
-void operator delete(void * ptr)
-#if __cplusplus < 201000L
-throw()
-#endif
+void operator delete(void * ptr) NOEXCEPT
 {
 	free(ptr);
 }
 
 
 __attribute__((weak))
-void * operator new[](size_t size)
-#if __cplusplus < 201000L
-throw(std::bad_alloc)
-#endif
+void * operator new[](size_t size) BADALLOC
 {
 	return ::operator new(size);
 }
 
 
 __attribute__((weak))
-void * operator new[](size_t size, const std::nothrow_t &) throw()
+void * operator new[](size_t size, const std::nothrow_t &) NOEXCEPT
 {
 	try {
 		return ::operator new[](size);
@@ -143,10 +146,7 @@ void * operator new[](size_t size, const
 
 
 __attribute__((weak))
-void operator delete[](void * ptr)
-#if __cplusplus < 201000L
-throw()
-#endif
+void operator delete[](void * ptr) NOEXCEPT
 {
 	::operator delete(ptr);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605052209.u45M9i0D087623>