[Midnightbsd-cvs] src [7451] trunk/contrib/libcxxrt: sync version with freebsd 10 stable

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Feb 28 16:26:58 EST 2016


Revision: 7451
          http://svnweb.midnightbsd.org/src/?rev=7451
Author:   laffer1
Date:     2016-02-28 16:26:57 -0500 (Sun, 28 Feb 2016)
Log Message:
-----------
sync version with freebsd 10  stable

Modified Paths:
--------------
    trunk/contrib/libcxxrt/auxhelper.cc
    trunk/contrib/libcxxrt/cxxabi.h
    trunk/contrib/libcxxrt/dwarf_eh.h
    trunk/contrib/libcxxrt/dynamic_cast.cc
    trunk/contrib/libcxxrt/exception.cc
    trunk/contrib/libcxxrt/guard.cc
    trunk/contrib/libcxxrt/libelftc_dem_gnu3.c
    trunk/contrib/libcxxrt/memory.cc
    trunk/contrib/libcxxrt/stdexcept.cc
    trunk/contrib/libcxxrt/stdexcept.h
    trunk/contrib/libcxxrt/typeinfo.cc
    trunk/contrib/libcxxrt/typeinfo.h
    trunk/contrib/libcxxrt/unwind-arm.h
    trunk/contrib/libcxxrt/unwind-itanium.h
    trunk/contrib/libcxxrt/unwind.h

Added Paths:
-----------
    trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade
    trunk/contrib/libcxxrt/atomic.h

Removed Paths:
-------------
    trunk/contrib/libcxxrt/FREEBSD-upgrade

Deleted: trunk/contrib/libcxxrt/FREEBSD-upgrade
===================================================================
--- trunk/contrib/libcxxrt/FREEBSD-upgrade	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/FREEBSD-upgrade	2016-02-28 21:26:57 UTC (rev 7451)
@@ -1,6 +0,0 @@
-$FreeBSD$
-
-This is the FreeBSD copy of libcxxrt.  It contains the src directory from the 
-upstream repository.
-
-When updating, copy *.{c,cc,h} and typeinfo from the upstream src/.

Copied: trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade (from rev 7446, trunk/contrib/libcxxrt/FREEBSD-upgrade)
===================================================================
--- trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade	                        (rev 0)
+++ trunk/contrib/libcxxrt/MIDNIGHTBSD-upgrade	2016-02-28 21:26:57 UTC (rev 7451)
@@ -0,0 +1,6 @@
+$MidnightBSD$
+
+This is the MidnightBSD copy of libcxxrt.  It contains the src directory from 
+the upstream repository.
+
+When updating, copy *.{c,cc,h} and typeinfo from the upstream src/.

Added: trunk/contrib/libcxxrt/atomic.h
===================================================================
--- trunk/contrib/libcxxrt/atomic.h	                        (rev 0)
+++ trunk/contrib/libcxxrt/atomic.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -0,0 +1,30 @@
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+/**
+ * Swap macro that enforces a happens-before relationship with a corresponding
+ * ATOMIC_LOAD.
+ */
+#if __has_builtin(__c11_atomic_exchange)
+#define ATOMIC_SWAP(addr, val)\
+	__c11_atomic_exchange(reinterpret_cast<_Atomic(__typeof__(val))*>(addr), val, __ATOMIC_ACQ_REL)
+#elif __has_builtin(__sync_swap)
+#define ATOMIC_SWAP(addr, val)\
+	__sync_swap(addr, val)
+#else
+#define ATOMIC_SWAP(addr, val)\
+	__sync_lock_test_and_set(addr, val)
+#endif
+
+#if __has_builtin(__c11_atomic_load)
+#define ATOMIC_LOAD(addr)\
+	__c11_atomic_load(reinterpret_cast<_Atomic(__typeof__(*addr))*>(addr), __ATOMIC_ACQUIRE)
+#else
+#define ATOMIC_LOAD(addr)\
+	(__sync_synchronize(), *addr)
+#endif
+


Property changes on: trunk/contrib/libcxxrt/atomic.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/contrib/libcxxrt/auxhelper.cc
===================================================================
--- trunk/contrib/libcxxrt/auxhelper.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/auxhelper.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -65,3 +65,18 @@
     abort();
 }
 
+/**
+ * Compilers may (but are not required to) set any deleted-virtual function's
+ * vtable entry to this function.  This makes debugging slightly easier, as
+ * users can add a breakpoint on this function to tell if they've accidentally
+ * called a deleted-virtual function.
+ */
+extern "C" void __cxa_deleted_virtual()
+{
+    abort();
+}
+
+extern "C" void __cxa_throw_bad_array_new_length()
+{
+	throw std::bad_array_new_length();
+}

Modified: trunk/contrib/libcxxrt/cxxabi.h
===================================================================
--- trunk/contrib/libcxxrt/cxxabi.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/cxxabi.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -22,6 +22,7 @@
 
 #ifndef __CXXABI_H_
 #define __CXXABI_H_
+#include <stddef.h>
 #include <stdint.h>
 #include "unwind.h"
 namespace std 
@@ -109,7 +110,7 @@
 	 * handler count reaches 0 (which it doesn't with the top bit set).
 	 */
 	int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	/**
 	 * The ARM EH ABI requires the unwind library to keep track of exceptions
 	 * during cleanups.  These support nesting, so we need to keep a list of
@@ -193,6 +194,8 @@
  */
 __cxa_eh_globals *__cxa_get_globals_fast(void);
 
+std::type_info * __cxa_current_exception_type();
+
 /**
  * Throws an exception returned by __cxa_current_primary_exception().  This
  * exception may have been caught in another thread.

Modified: trunk/contrib/libcxxrt/dwarf_eh.h
===================================================================
--- trunk/contrib/libcxxrt/dwarf_eh.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/dwarf_eh.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -57,6 +57,8 @@
 /// DWARF data encoding types.  
 enum dwarf_data_encoding
 {
+	/// Absolute pointer value
+	DW_EH_PE_absptr   = 0x00,
 	/// Unsigned, little-endian, base 128-encoded (variable length).
 	DW_EH_PE_uleb128 = 0x01,
 	/// Unsigned 16-bit integer.
@@ -81,7 +83,7 @@
  */
 static inline enum dwarf_data_encoding get_encoding(unsigned char x)
 {
-	return (enum dwarf_data_encoding)(x & 0xf);
+	return static_cast<enum dwarf_data_encoding>(x & 0xf);
 }
 
 /**
@@ -95,8 +97,6 @@
 {
 	/// Value is omitted
 	DW_EH_PE_omit     = 0xff,
-	/// Absolute pointer value
-	DW_EH_PE_absptr   = 0x00,
 	/// Value relative to program counter
 	DW_EH_PE_pcrel    = 0x10,
 	/// Value relative to the text segment
@@ -115,7 +115,7 @@
  */
 static inline enum dwarf_data_relative get_base(unsigned char x)
 {
-	return (enum dwarf_data_relative)(x & 0x70);
+	return static_cast<enum dwarf_data_relative>(x & 0x70);
 }
 /**
  * Returns whether an encoding represents an indirect address.
@@ -206,9 +206,9 @@
 	if ((uleb >> (bits-1)) == 1)
 	{
 		// Sign extend by setting all bits in front of it to 1
-		uleb |= ((int64_t)-1) << bits;
+		uleb |= static_cast<int64_t>(-1) << bits;
 	}
-	return (int64_t)uleb;
+	return static_cast<int64_t>(uleb);
 }
 /**
  * Reads a value using the specified encoding from the address pointed to by
@@ -218,15 +218,17 @@
 static uint64_t read_value(char encoding, dw_eh_ptr_t *data)
 {
 	enum dwarf_data_encoding type = get_encoding(encoding);
-	uint64_t v;
 	switch (type)
 	{
 		// Read fixed-length types
 #define READ(dwarf, type) \
 		case dwarf:\
-			v = (uint64_t)(*(type*)(*data));\
-			*data += sizeof(type);\
-			break;
+		{\
+			type t;\
+			memcpy(&t, *data, sizeof t);\
+			*data += sizeof t;\
+			return static_cast<uint64_t>(t);\
+		}
 		READ(DW_EH_PE_udata2, uint16_t)
 		READ(DW_EH_PE_udata4, uint32_t)
 		READ(DW_EH_PE_udata8, uint64_t)
@@ -237,15 +239,11 @@
 #undef READ
 		// Read variable-length types
 		case DW_EH_PE_sleb128:
-			v = read_sleb128(data);
-			break;
+			return read_sleb128(data);
 		case DW_EH_PE_uleb128:
-			v = read_uleb128(data);
-			break;
+			return read_uleb128(data);
 		default: abort();
 	}
-
-	return v;
 }
 
 /**
@@ -263,16 +261,16 @@
 	switch (get_base(encoding))
 	{
 		case DW_EH_PE_pcrel:
-			v += (uint64_t)start;
+			v += reinterpret_cast<uint64_t>(start);
 			break;
 		case DW_EH_PE_textrel:
-			v += (uint64_t)_Unwind_GetTextRelBase(c);
+			v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetTextRelBase(c)));
 			break;
 		case DW_EH_PE_datarel:
-			v += (uint64_t)_Unwind_GetDataRelBase(c);
+			v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetDataRelBase(c)));
 			break;
 		case DW_EH_PE_funcrel:
-			v += (uint64_t)_Unwind_GetRegionStart(c);
+			v += static_cast<uint64_t>(static_cast<uintptr_t>(_Unwind_GetRegionStart(c)));
 		default:
 			break;
 	}
@@ -282,7 +280,7 @@
 	// be a GCC extensions, so not properly documented...
 	if (is_indirect(encoding))
 	{
-		v = (uint64_t)(uintptr_t)*(void**)v;
+		v = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(*reinterpret_cast<void**>(v)));
 	}
 	return v;
 }
@@ -342,14 +340,14 @@
 {
 	struct dwarf_eh_lsda lsda;
 
-	lsda.region_start = (dw_eh_ptr_t)(uintptr_t)_Unwind_GetRegionStart(context);
+	lsda.region_start = reinterpret_cast<dw_eh_ptr_t>(_Unwind_GetRegionStart(context));
 
 	// If the landing pads are relative to anything other than the start of
 	// this region, find out where.  This is @LPStart in the spec, although the
 	// encoding that GCC uses does not quite match the spec.
-	uint64_t v = (uint64_t)(uintptr_t)lsda.region_start;
+	uint64_t v = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(lsda.region_start));
 	read_value_with_encoding(context, &data, &v);
-	lsda.landing_pads = (dw_eh_ptr_t)(uintptr_t)v;
+	lsda.landing_pads = reinterpret_cast<dw_eh_ptr_t>(static_cast<uintptr_t>(v));
 
 	// If there is a type table, find out where it is.  This is @TTBase in the
 	// spec.  Note: we find whether there is a type table pointer by checking
@@ -365,18 +363,18 @@
 		lsda.type_table = type_table;
 		//lsda.type_table = (uintptr_t*)(data + v);
 	}
-#if __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	lsda.type_table_encoding = (DW_EH_PE_pcrel | DW_EH_PE_indirect);
 #endif
 
-	lsda.callsite_encoding = (enum dwarf_data_encoding)(*(data++));
+	lsda.callsite_encoding = static_cast<enum dwarf_data_encoding>(*(data++));
 
 	// Action table is immediately after the call site table
 	lsda.action_table = data;
-	uintptr_t callsite_size = (uintptr_t)read_uleb128(&data);
+	uintptr_t callsite_size = static_cast<uintptr_t>(read_uleb128(&data));
 	lsda.action_table = data + callsite_size;
 	// Call site table is immediately after the header
-	lsda.call_site_table = (dw_eh_ptr_t)data;
+	lsda.call_site_table = static_cast<dw_eh_ptr_t>(data);
 
 
 	return lsda;
@@ -413,7 +411,7 @@
 	result->landing_pad = 0;
 	// The current instruction pointer offset within the region
 	uint64_t ip = _Unwind_GetIP(context) - _Unwind_GetRegionStart(context);
-	unsigned char *callsite_table = (unsigned char*)lsda->call_site_table;
+	unsigned char *callsite_table = static_cast<unsigned char*>(lsda->call_site_table);
 
 	while (callsite_table <= lsda->action_table)
 	{
@@ -463,17 +461,17 @@
 
 /// Defines an exception class from 8 bytes (endian independent)
 #define EXCEPTION_CLASS(a,b,c,d,e,f,g,h) \
-	(((uint64_t)a << 56) +\
-	 ((uint64_t)b << 48) +\
-	 ((uint64_t)c << 40) +\
-	 ((uint64_t)d << 32) +\
-	 ((uint64_t)e << 24) +\
-	 ((uint64_t)f << 16) +\
-	 ((uint64_t)g << 8) +\
-	 ((uint64_t)h))
+	((static_cast<uint64_t>(a) << 56) +\
+	 (static_cast<uint64_t>(b) << 48) +\
+	 (static_cast<uint64_t>(c) << 40) +\
+	 (static_cast<uint64_t>(d) << 32) +\
+	 (static_cast<uint64_t>(e) << 24) +\
+	 (static_cast<uint64_t>(f) << 16) +\
+	 (static_cast<uint64_t>(g) << 8) +\
+	 (static_cast<uint64_t>(h)))
 
 #define GENERIC_EXCEPTION_CLASS(e,f,g,h) \
-	 ((uint32_t)e << 24) +\
-	 ((uint32_t)f << 16) +\
-	 ((uint32_t)g << 8) +\
-	 ((uint32_t)h)
+	 (static_cast<uint32_t>(e) << 24) +\
+	 (static_cast<uint32_t>(f) << 16) +\
+	 (static_cast<uint32_t>(g) << 8) +\
+	 (static_cast<uint32_t>(h))

Modified: trunk/contrib/libcxxrt/dynamic_cast.cc
===================================================================
--- trunk/contrib/libcxxrt/dynamic_cast.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/dynamic_cast.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -44,7 +44,7 @@
  * Simple macro that does pointer arithmetic in bytes but returns a value of
  * the same type as the original.
  */
-#define ADD_TO_PTR(x, off) (__typeof__(x))(((char*)x) + off)
+#define ADD_TO_PTR(x, off) reinterpret_cast<__typeof__(x)>(reinterpret_cast<char*>(x) + off)
 
 bool std::type_info::__do_catch(std::type_info const *ex_type,
                                 void **exception_object,
@@ -166,7 +166,7 @@
 		if (info->isVirtual())
 		{
 			// Object's vtable
-			ptrdiff_t *off = *(ptrdiff_t**)obj;
+			ptrdiff_t *off = *static_cast<ptrdiff_t**>(obj);
 			// Offset location in vtable
 			off = ADD_TO_PTR(off, offset);
 			offset = *off;
@@ -202,9 +202,9 @@
                                 const __class_type_info *dst,
                                 ptrdiff_t src2dst_offset)
 {
-	char *vtable_location = *(char**)sub;
+	const char *vtable_location = *static_cast<const char * const *>(sub);
 	const vtable_header *header =
-		(const vtable_header*)(vtable_location - sizeof(vtable_header));
-	void *leaf = ADD_TO_PTR((void*)sub, header->leaf_offset);
+		reinterpret_cast<const vtable_header*>(vtable_location - sizeof(vtable_header));
+	void *leaf = ADD_TO_PTR(const_cast<void *>(sub), header->leaf_offset);
 	return header->type->cast_to(leaf, dst);
 }

Modified: trunk/contrib/libcxxrt/exception.cc
===================================================================
--- trunk/contrib/libcxxrt/exception.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/exception.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -32,6 +32,7 @@
 #include <pthread.h>
 #include "typeinfo.h"
 #include "dwarf_eh.h"
+#include "atomic.h"
 #include "cxxabi.h"
 
 #pragma weak pthread_key_create
@@ -38,6 +39,24 @@
 #pragma weak pthread_setspecific
 #pragma weak pthread_getspecific
 #pragma weak pthread_once
+#ifdef LIBCXXRT_WEAK_LOCKS
+#pragma weak pthread_mutex_lock
+#define pthread_mutex_lock(mtx) do {\
+	if (pthread_mutex_lock) pthread_mutex_lock(mtx);\
+	} while(0)
+#pragma weak pthread_mutex_unlock
+#define pthread_mutex_unlock(mtx) do {\
+	if (pthread_mutex_unlock) pthread_mutex_unlock(mtx);\
+	} while(0)
+#pragma weak pthread_cond_signal
+#define pthread_cond_signal(cv) do {\
+	if (pthread_cond_signal) pthread_cond_signal(cv);\
+	} while(0)
+#pragma weak pthread_cond_wait
+#define pthread_cond_wait(cv, mtx) do {\
+	if (pthread_cond_wait) pthread_cond_wait(cv, mtx);\
+	} while(0)
+#endif
 
 using namespace ABI_NAMESPACE;
 
@@ -52,11 +71,11 @@
                            int selector,
                            dw_eh_ptr_t landingPad)
 {
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	// On ARM, we store the saved exception in the generic part of the structure
 	ucb->barrier_cache.sp = _Unwind_GetGR(context, 13);
-	ucb->barrier_cache.bitpattern[1] = (uint32_t)selector;
-	ucb->barrier_cache.bitpattern[3] = (uint32_t)landingPad;
+	ucb->barrier_cache.bitpattern[1] = static_cast<uint32_t>(selector);
+	ucb->barrier_cache.bitpattern[3] = reinterpret_cast<uint32_t>(landingPad);
 #endif
 	// Cache the results for the phase 2 unwind, if we found a handler
 	// and this is not a foreign exception.  
@@ -76,15 +95,15 @@
                           unsigned long *selector,
                           dw_eh_ptr_t *landingPad)
 {
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	*selector = ucb->barrier_cache.bitpattern[1];
-	*landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3];
+	*landingPad = reinterpret_cast<dw_eh_ptr_t>(ucb->barrier_cache.bitpattern[3]);
 	return 1;
 #else
 	if (ex)
 	{
 		*selector = ex->handlerSwitchValue;
-		*landingPad = (dw_eh_ptr_t)ex->catchTemp;
+		*landingPad = reinterpret_cast<dw_eh_ptr_t>(ex->catchTemp);
 		return 0;
 	}
 	return 0;
@@ -94,7 +113,7 @@
 static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex,
                                                     struct _Unwind_Context *context)
 {
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
 #endif
 	return _URC_CONTINUE_UNWIND;
@@ -155,6 +174,17 @@
 	 */
 	_Unwind_Exception *currentCleanup;
 	/**
+	 * Our state with respect to foreign exceptions.  Usually none, set to
+	 * caught if we have just caught an exception and rethrown if we are
+	 * rethrowing it.
+	 */
+	enum 
+	{
+		none,
+		caught,
+		rethrown
+	} foreign_exception_state;
+	/**
 	 * The public part of this structure, accessible from outside of this
 	 * module.
 	 */
@@ -174,7 +204,7 @@
 	terminate_handler terminateHandler;
 	__cxa_exception *nextException;
 	int handlerCount;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	_Unwind_Exception *nextCleanup;
 	int cleanupCount;
 #endif
@@ -202,8 +232,6 @@
 
 }
 
-extern "C" std::type_info *__cxa_current_exception_type();
-
 /**
  * Class of exceptions to distinguish between this and other exception types.
  *
@@ -239,13 +267,13 @@
 
 static __cxa_exception *exceptionFromPointer(void *ex)
 {
-	return (__cxa_exception*)((char*)ex -
+	return reinterpret_cast<__cxa_exception*>(static_cast<char*>(ex) -
 			offsetof(struct __cxa_exception, unwindHeader));
 }
 static __cxa_exception *realExceptionFromException(__cxa_exception *ex)
 {
 	if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; }
-	return ((__cxa_exception*)(((__cxa_dependent_exception*)ex)->primaryException))-1;
+	return reinterpret_cast<__cxa_exception*>((reinterpret_cast<__cxa_dependent_exception*>(ex))->primaryException)-1;
 }
 
 
@@ -276,13 +304,13 @@
 static void exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
-	__cxa_free_exception((void*)ex);
+	__cxa_free_exception(static_cast<void*>(ex));
 }
 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
 
-	__cxa_free_dependent_exception((void*)ex);
+	__cxa_free_dependent_exception(static_cast<void*>(ex));
 }
 
 /**
@@ -305,10 +333,19 @@
  */
 static void thread_cleanup(void* thread_info)
 {
-	__cxa_thread_info *info = (__cxa_thread_info*)thread_info;
+	__cxa_thread_info *info = static_cast<__cxa_thread_info*>(thread_info);
 	if (info->globals.caughtExceptions)
 	{
-		free_exception_list(info->globals.caughtExceptions);
+		// If this is a foreign exception, ask it to clean itself up.
+		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);
+		}
+		else
+		{
+			free_exception_list(info->globals.caughtExceptions);
+		}
 	}
 	free(thread_info);
 }
@@ -342,8 +379,8 @@
 		return;
 	}
 	pthread_key_create(&eh_key, thread_cleanup);
-	pthread_setspecific(eh_key, (void*)0x42);
-	fakeTLS = (pthread_getspecific(eh_key) != (void*)0x42);
+	pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42));
+	fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42));
 	pthread_setspecific(eh_key, 0);
 }
 
@@ -357,10 +394,10 @@
 		fakeTLS = true;
 	}
 	if (fakeTLS) { return &singleThreadInfo; }
-	__cxa_thread_info *info = (__cxa_thread_info*)pthread_getspecific(eh_key);
+	__cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
 	if (0 == info)
 	{
-		info = (__cxa_thread_info*)calloc(1, sizeof(__cxa_thread_info));
+		info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info)));
 		pthread_setspecific(eh_key, info);
 	}
 	return info;
@@ -372,7 +409,7 @@
 static __cxa_thread_info *thread_info_fast()
 {
 	if (fakeTLS) { return &singleThreadInfo; }
-	return (__cxa_thread_info*)pthread_getspecific(eh_key);
+	return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
 }
 /**
  * ABI function returning the __cxa_eh_globals structure.
@@ -435,7 +472,7 @@
 		if (0 != m)
 		{
 			pthread_mutex_unlock(&emergency_malloc_lock);
-			return (char*)m;
+			return static_cast<char*>(m);
 		}
 		for (int i=0 ; i<16 ; i++)
 		{
@@ -473,18 +510,18 @@
 	// Find the buffer corresponding to this pointer.
 	for (int i=0 ; i<16 ; i++)
 	{
-		if (ptr == (void*)(emergency_buffer + (1024 * i)))
+		if (ptr == static_cast<void*>(emergency_buffer + (1024 * i)))
 		{
 			buffer = i;
 			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
 	// begin life containing 0 values.
-	memset((void*)ptr, 0, 1024);
+	memset(ptr, 0, 1024);
 	// Signal the condition variable to wake up any threads that are blocking
 	// waiting for some space in the emergency buffer
 	pthread_mutex_lock(&emergency_malloc_lock);
@@ -498,7 +535,7 @@
 
 static char *alloc_or_die(size_t size)
 {
-	char *buffer = (char*)calloc(1, size);
+	char *buffer = static_cast<char*>(calloc(1, size));
 
 	// If calloc() doesn't want to give us any memory, try using an emergency
 	// buffer.
@@ -519,7 +556,7 @@
 {
 	// 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);
@@ -560,7 +597,7 @@
  */
 extern "C" void __cxa_free_exception(void *thrown_exception)
 {
-	__cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+	__cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1;
 	// Free the object that was thrown, calling its destructor
 	if (0 != ex->exceptionDestructor)
 	{
@@ -575,7 +612,7 @@
 		}
 	}
 
-	free_exception((char*)ex);
+	free_exception(reinterpret_cast<char*>(ex));
 }
 
 static void releaseException(__cxa_exception *exception)
@@ -596,13 +633,13 @@
 
 void __cxa_free_dependent_exception(void *thrown_exception)
 {
-	__cxa_dependent_exception *ex = ((__cxa_dependent_exception*)thrown_exception) - 1;
+	__cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(thrown_exception) - 1;
 	assert(isDependentException(ex->unwindHeader.exception_class));
 	if (ex->primaryException)
 	{
-		releaseException(realExceptionFromException((__cxa_exception*)ex));
+		releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
 	}
-	free_exception((char*)ex);
+	free_exception(reinterpret_cast<char*>(ex));
 }
 
 /**
@@ -617,8 +654,8 @@
 {
 	Dl_info myinfo;
 	int mylookup =
-		dladdr((void*)(uintptr_t)__cxa_current_exception_type, &myinfo);
-	void *ip = (void*)_Unwind_GetIP(context);
+		dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo);
+	void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context));
 	Dl_info info;
 	if (dladdr(ip, &info) != 0)
 	{
@@ -636,6 +673,11 @@
  * If the failure happened by falling off the end of the stack without finding
  * a handler, prints a back trace before aborting.
  */
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+extern "C" void *__cxa_begin_catch(void *e) throw();
+#else
+extern "C" void *__cxa_begin_catch(void *e);
+#endif
 static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception)
 {
 	switch (err)
@@ -644,14 +686,16 @@
 		case _URC_FATAL_PHASE1_ERROR:
 			fprintf(stderr, "Fatal error during phase 1 unwinding\n");
 			break;
-#ifndef __arm__
+#if !defined(__arm__) || defined(__ARM_DWARF_EH__)
 		case _URC_FATAL_PHASE2_ERROR:
 			fprintf(stderr, "Fatal error during phase 2 unwinding\n");
 			break;
 #endif
 		case _URC_END_OF_STACK:
+			__cxa_begin_catch (&(thrown_exception->unwindHeader));
+ 			std::terminate();
 			fprintf(stderr, "Terminating due to uncaught exception %p", 
-					(void*)thrown_exception);
+					static_cast<void*>(thrown_exception));
 			thrown_exception = realExceptionFromException(thrown_exception);
 			static const __class_type_info *e_ti =
 				static_cast<const __class_type_info*>(&typeid(std::exception));
@@ -660,8 +704,8 @@
 			if (throw_ti)
 			{
 				std::exception *e =
-					(std::exception*)e_ti->cast_to((void*)(thrown_exception+1),
-							throw_ti);
+					static_cast<std::exception*>(e_ti->cast_to(static_cast<void*>(thrown_exception+1),
+							throw_ti));
 				if (e)
 				{
 					fprintf(stderr, " '%s'", e->what());
@@ -669,16 +713,21 @@
 			}
 
 			size_t bufferSize = 128;
-			char *demangled = (char*)malloc(bufferSize);
+			char *demangled = static_cast<char*>(malloc(bufferSize));
 			const char *mangled = thrown_exception->exceptionType->name();
 			int status;
 			demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
 			fprintf(stderr, " of type %s\n", 
-				status == 0 ? (const char*)demangled : mangled);
+				status == 0 ? demangled : mangled);
 			if (status == 0) { free(demangled); }
 			// Print a back trace if no handler is found.
 			// TODO: Make this optional
+#ifndef __arm__
 			_Unwind_Backtrace(trace, 0);
+#endif
+
+			// Just abort. No need to call std::terminate for the second time
+			abort();
 			break;
 	}
 	std::terminate();
@@ -716,7 +765,7 @@
                             std::type_info *tinfo,
                             void(*dest)(void*))
 {
-	__cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+	__cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1;
 
 	ex->referenceCount = 1;
 	ex->exceptionType = tinfo;
@@ -734,7 +783,7 @@
 	if (NULL == thrown_exception) { return; }
 
 	__cxa_exception *original = exceptionFromPointer(thrown_exception);
-	__cxa_dependent_exception *ex = ((__cxa_dependent_exception*)__cxa_allocate_dependent_exception())-1;
+	__cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception())-1;
 
 	ex->primaryException = thrown_exception;
 	__cxa_increment_exception_refcount(thrown_exception);
@@ -743,7 +792,7 @@
 	ex->unwindHeader.exception_class = dependent_exception_class;
 	ex->unwindHeader.exception_cleanup = dependent_exception_cleanup;
 
-	throw_exception((__cxa_exception*)ex);
+	throw_exception(reinterpret_cast<__cxa_exception*>(ex));
 }
 
 extern "C" void *__cxa_current_primary_exception(void)
@@ -760,7 +809,7 @@
 extern "C" void __cxa_increment_exception_refcount(void* thrown_exception)
 {
 	if (NULL == thrown_exception) { return; }
-	__cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+	__cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1;
 	if (isDependentException(ex->unwindHeader.exception_class)) { return; }
 	__sync_fetch_and_add(&ex->referenceCount, 1);
 }
@@ -767,7 +816,7 @@
 extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception)
 {
 	if (NULL == thrown_exception) { return; }
-	__cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+	__cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1;
 	releaseException(ex);
 }
 
@@ -780,7 +829,8 @@
  */
 extern "C" void __cxa_rethrow()
 {
-	__cxa_eh_globals *globals = __cxa_get_globals();
+	__cxa_thread_info *ti = thread_info();
+	__cxa_eh_globals *globals = &ti->globals;
 	// Note: We don't remove this from the caught list here, because
 	// __cxa_end_catch will be called when we unwind out of the try block.  We
 	// could probably make this faster by providing an alternative rethrow
@@ -795,6 +845,15 @@
 		std::terminate();
 	}
 
+	if (ti->foreign_exception_state != __cxa_thread_info::none)
+	{
+		ti->foreign_exception_state = __cxa_thread_info::rethrown;
+		_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ex);
+		_Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(e);
+		report_failure(err, ex);
+		return;
+	}
+
 	assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!");
 
 	// ex->handlerCount will be decremented in __cxa_end_catch in enclosing
@@ -832,8 +891,8 @@
 	if (offset == 0) { return 0; }
 
 	// ...so we need to resolve it
-	return (std::type_info*)resolve_indirect_value(context,
-			lsda->type_table_encoding, offset, start);
+	return reinterpret_cast<std::type_info*>(resolve_indirect_value(context,
+			lsda->type_table_encoding, offset, start));
 }
 
 
@@ -847,13 +906,13 @@
                                  const std::type_info *type,
                                  void *&adjustedPtr)
 {
-	void *exception_ptr = (void*)(ex+1);
-	const std::type_info *ex_type = ex->exceptionType;
+	void *exception_ptr = static_cast<void*>(ex+1);
+	const std::type_info *ex_type = ex ? ex->exceptionType : 0;
 
-	bool is_ptr = ex_type->__is_pointer_p();
+	bool is_ptr = ex ? ex_type->__is_pointer_p() : false;
 	if (is_ptr)
 	{
-		exception_ptr = *(void**)exception_ptr;
+		exception_ptr = *static_cast<void**>(exception_ptr);
 	}
 	// Always match a catchall, even with a foreign exception
 	//
@@ -911,8 +970,8 @@
 		action_record = displacement ? 
 			action_record_offset_base + displacement : 0;
 		// We only check handler types for C++ exceptions - foreign exceptions
-		// are only allowed for cleanup.
-		if (filter > 0 && 0 != ex)
+		// are only allowed for cleanups and catchalls.
+		if (filter > 0)
 		{
 			std::type_info *handler_type = get_type_info_entry(context, lsda, filter);
 			if (check_type_signature(ex, handler_type, adjustedPtr))
@@ -925,7 +984,7 @@
 		{
 			bool matched = false;
 			*selector = filter;
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 			filter++;
 			std::type_info *handler_type = get_type_info_entry(context, lsda, filter--);
 			while (handler_type)
@@ -938,7 +997,7 @@
 				handler_type = get_type_info_entry(context, lsda, filter--);
 			}
 #else
-			unsigned char *type_index = ((unsigned char*)lsda->type_table - filter - 1);
+			unsigned char *type_index = reinterpret_cast<unsigned char*>(lsda->type_table) - filter - 1;
 			while (*type_index)
 			{
 				std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++));
@@ -970,7 +1029,7 @@
 static void pushCleanupException(_Unwind_Exception *exceptionObject,
                                  __cxa_exception *ex)
 {
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	__cxa_thread_info *info = thread_info_fast();
 	if (ex)
 	{
@@ -1015,8 +1074,13 @@
 		realEx = realExceptionFromException(ex);
 	}
 
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 	unsigned char *lsda_addr =
-		(unsigned char*)_Unwind_GetLanguageSpecificData(context);
+		static_cast<unsigned char*>(_Unwind_GetLanguageSpecificData(context));
+#else
+	unsigned char *lsda_addr =
+		reinterpret_cast<unsigned char*>(static_cast<uintptr_t>(_Unwind_GetLanguageSpecificData(context)));
+#endif
 
 	// No LSDA implies no landing pads - try the next frame
 	if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); }
@@ -1065,8 +1129,8 @@
 			if (ex)
 			{
 				saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad);
-				ex->languageSpecificData = (const char*)lsda_addr;
-				ex->actionRecord = (const char*)action.action_record;
+				ex->languageSpecificData = reinterpret_cast<const char*>(lsda_addr);
+				ex->actionRecord = reinterpret_cast<const char*>(action.action_record);
 				// ex->adjustedPtr is set when finding the action record.
 			}
 			return _URC_HANDLER_FOUND;
@@ -1112,9 +1176,9 @@
 	}
 
 
-	_Unwind_SetIP(context, (unsigned long)action.landing_pad);
+	_Unwind_SetIP(context, reinterpret_cast<unsigned long>(action.landing_pad));
 	_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
-	              (unsigned long)exceptionObject);
+	              reinterpret_cast<unsigned long>(exceptionObject));
 	_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
 
 	return _URC_INSTALL_CONTEXT;
@@ -1127,16 +1191,18 @@
  * pointer to the caught exception, which is either the adjusted pointer (for
  * C++ exceptions) of the unadjusted pointer (for foreign exceptions).
  */
-#if __GNUC__ > 3 && __GNUC_MINOR__ > 2
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
 extern "C" void *__cxa_begin_catch(void *e) throw()
 #else
 extern "C" void *__cxa_begin_catch(void *e)
 #endif
 {
-	// Decrement the uncaught exceptions count
-	__cxa_eh_globals *globals = __cxa_get_globals();
+	// We can't call the fast version here, because if the first exception that
+	// we see is a foreign exception then we won't have called it yet.
+	__cxa_thread_info *ti = thread_info();
+	__cxa_eh_globals *globals = &ti->globals;
 	globals->uncaughtExceptions--;
-	_Unwind_Exception *exceptionObject = (_Unwind_Exception*)e;
+	_Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(e);
 
 	if (isCXXException(exceptionObject->exception_class))
 	{
@@ -1177,12 +1243,25 @@
 		{
 			ex->handlerCount++;
 		}
+		ti->foreign_exception_state = __cxa_thread_info::none;
 		
 		return ex->adjustedPtr;
 	}
+	else
+	{
+		// If this is a foreign exception, then we need to be able to
+		// store it.  We can't chain foreign exceptions, so we give up
+		// if there are already some outstanding ones.
+		if (globals->caughtExceptions != 0)
+		{
+			std::terminate();
+		}
+		globals->caughtExceptions = reinterpret_cast<__cxa_exception*>(exceptionObject);
+		ti->foreign_exception_state = __cxa_thread_info::caught;
+	}
 	// exceptionObject is the pointer to the _Unwind_Exception within the
 	// __cxa_exception.  The throw object is after this
-	return ((char*)exceptionObject + sizeof(_Unwind_Exception));
+	return (reinterpret_cast<char*>(exceptionObject) + sizeof(_Unwind_Exception));
 }
 
 
@@ -1195,10 +1274,23 @@
 {
 	// We can call the fast version here because the slow version is called in
 	// __cxa_throw(), which must have been called before we end a catch block
-	__cxa_eh_globals *globals = __cxa_get_globals_fast();
+	__cxa_thread_info *ti = thread_info_fast();
+	__cxa_eh_globals *globals = &ti->globals;
 	__cxa_exception *ex = globals->caughtExceptions;
 
 	assert(0 != ex && "Ending catch when no exception is on the stack!");
+	
+	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);
+		}
+		ti->foreign_exception_state = __cxa_thread_info::none;
+		return;
+	}
 
 	bool deleteException = true;
 
@@ -1255,7 +1347,7 @@
  */
 extern "C" void __cxa_call_unexpected(void*exception) 
 {
-	_Unwind_Exception *exceptionObject = (_Unwind_Exception*)exception;
+	_Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(exception);
 	if (exceptionObject->exception_class == exception_class)
 	{
 		__cxa_exception *ex =  exceptionFromPointer(exceptionObject);
@@ -1328,7 +1420,7 @@
 	{
 		if (thread_local_handlers) { return pathscale::set_unexpected(f); }
 
-		return __sync_lock_test_and_set(&unexpectedHandler, f);
+		return ATOMIC_SWAP(&unexpectedHandler, f);
 	}
 	/**
 	 * Sets the function that is called to terminate the program.
@@ -1336,7 +1428,8 @@
 	terminate_handler set_terminate(terminate_handler f) throw()
 	{
 		if (thread_local_handlers) { return pathscale::set_terminate(f); }
-		return __sync_lock_test_and_set(&terminateHandler, f);
+
+		return ATOMIC_SWAP(&terminateHandler, f);
 	}
 	/**
 	 * Terminates the program, calling a custom terminate implementation if
@@ -1344,7 +1437,7 @@
 	 */
 	void terminate()
 	{
-		static __cxa_thread_info *info = thread_info_fast();
+		static __cxa_thread_info *info = thread_info();
 		if (0 != info && 0 != info->terminateHandler)
 		{
 			info->terminateHandler();
@@ -1361,7 +1454,7 @@
 	 */
 	void unexpected()
 	{
-		static __cxa_thread_info *info = thread_info_fast();
+		static __cxa_thread_info *info = thread_info();
 		if (0 != info && 0 != info->unexpectedHandler)
 		{
 			info->unexpectedHandler();
@@ -1390,7 +1483,7 @@
 		{
 			return info->unexpectedHandler;
 		}
-		return unexpectedHandler;
+		return ATOMIC_LOAD(&unexpectedHandler);
 	}
 	/**
 	 * Returns the current terminate handler.
@@ -1402,10 +1495,10 @@
 		{
 			return info->terminateHandler;
 		}
-		return terminateHandler;
+		return ATOMIC_LOAD(&terminateHandler);
 	}
 }
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
 {
 	__cxa_thread_info *info = thread_info_fast();

Modified: trunk/contrib/libcxxrt/guard.cc
===================================================================
--- trunk/contrib/libcxxrt/guard.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/guard.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -41,104 +41,125 @@
  * initialised.  
  */
 #include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
 #include <pthread.h>
 #include <assert.h>
+#include "atomic.h"
 
-#ifdef __arm__
-// ARM ABI - 32-bit guards.
+// Older GCC doesn't define __LITTLE_ENDIAN__
+#ifndef __LITTLE_ENDIAN__
+	// If __BYTE_ORDER__ is defined, use that instead
+#	ifdef __BYTE_ORDER__
+#		if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#			define __LITTLE_ENDIAN__
+#		endif
+	// x86 and ARM are the most common little-endian CPUs, so let's have a
+	// special case for them (ARM is already special cased).  Assume everything
+	// else is big endian.
+#	elif defined(__x86_64) || defined(__i386)
+#		define __LITTLE_ENDIAN__
+#	endif
+#endif
 
-/**
- * Acquires a lock on a guard, returning 0 if the object has already been
- * initialised, and 1 if it has not.  If the object is already constructed then
- * this function just needs to read a byte from memory and return.
- */
-extern "C" int __cxa_guard_acquire(volatile int32_t *guard_object)
-{
-	if ((1<<31) == *guard_object) { return 0; }
-	// If we can atomically move the value from 0 -> 1, then this is
-	// uninitialised.
-	if (__sync_bool_compare_and_swap(guard_object, 0, 1))
-	{
-		return 1;
-	}
-	// If the value is not 0, some other thread was initialising this.  Spin
-	// until it's finished.
-	while (__sync_bool_compare_and_swap(guard_object, (1<<31), (1<<31)))
-	{
-		// If the other thread aborted, then we grab the lock
-		if (__sync_bool_compare_and_swap(guard_object, 0, 1))
-		{
-			return 1;
-		}
-		sched_yield();
-	}
-	return 0;
-}
 
-/**
- * Releases the lock without marking the object as initialised.  This function
- * is called if initialising a static causes an exception to be thrown.
+/*
+ * The least significant bit of the guard variable indicates that the object
+ * has been initialised, the most significant bit is used for a spinlock.
  */
-extern "C" void __cxa_guard_abort(int32_t *guard_object)
-{
-	assert(__sync_bool_compare_and_swap(guard_object, 1, 0));
-}
-/**
- * Releases the guard and marks the object as initialised.  This function is
- * called after successful initialisation of a static.
- */
-extern "C" void __cxa_guard_release(int32_t *guard_object)
-{
-	assert(__sync_bool_compare_and_swap(guard_object, 1, (1<<31)));
-}
-
-
+#ifdef __arm__
+// ARM ABI - 32-bit guards.
+typedef uint32_t guard_t;
+typedef uint32_t guard_lock_t;
+static const uint32_t LOCKED = static_cast<guard_t>(1) << 31;
+static const uint32_t INITIALISED = 1;
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
+#elif defined(_LP64)
+typedef uint64_t guard_t;
+typedef uint64_t guard_lock_t;
+#	if defined(__LITTLE_ENDIAN__)
+static const guard_t LOCKED = static_cast<guard_t>(1) << 63;
+static const guard_t INITIALISED = 1;
+#	else
+static const guard_t LOCKED = 1;
+static const guard_t INITIALISED = static_cast<guard_t>(1) << 56;
+#	endif
+#define LOCK_PART(guard) (guard)
+#define INIT_PART(guard) (guard)
 #else
-// Itanium ABI: 64-bit guards
+typedef uint32_t guard_lock_t;
+#	if defined(__LITTLE_ENDIAN__)
+typedef struct {
+	uint32_t init_half;
+	uint32_t lock_half;
+} guard_t;
+static const uint32_t LOCKED = static_cast<guard_lock_t>(1) << 31;
+static const uint32_t INITIALISED = 1;
+#	else
+typedef struct {
+	uint32_t init_half;
+	uint32_t lock_half;
+} guard_t;
+_Static_assert(sizeof(guard_t) == sizeof(uint64_t), "");
+static const uint32_t LOCKED = 1;
+static const uint32_t INITIALISED = static_cast<guard_lock_t>(1) << 24;
+#	endif
+#define LOCK_PART(guard) (&(guard)->lock_half)
+#define INIT_PART(guard) (&(guard)->init_half)
+#endif
+static const guard_lock_t INITIAL = 0;
 
 /**
- * Returns a pointer to the low 32 bits in a 64-bit value, respecting the
- * platform's byte order.
- */
-static int32_t *low_32_bits(volatile int64_t *ptr)
-{
-	int32_t *low= (int32_t*)ptr;
-	// Test if the machine is big endian - constant propagation at compile time
-	// should eliminate this completely.
-	int one = 1;
-	if (*(char*)&one != 1)
-	{
-		low++;
-	}
-	return low;
-}
-
-/**
  * Acquires a lock on a guard, returning 0 if the object has already been
  * initialised, and 1 if it has not.  If the object is already constructed then
  * this function just needs to read a byte from memory and return.
  */
-extern "C" int __cxa_guard_acquire(volatile int64_t *guard_object)
+extern "C" int __cxa_guard_acquire(volatile guard_t *guard_object)
 {
-	char first_byte = (*guard_object) >> 56;
-	if (1 == first_byte) { return 0; }
-	int32_t *lock = low_32_bits(guard_object);
-	// Simple spin lock using the low 32 bits.  We assume that concurrent
-	// attempts to initialize statics are very rare, so we don't need to
-	// optimise for the case where we have lots of threads trying to acquire
-	// the lock at the same time.
-	while (!__sync_bool_compare_and_swap_4(lock, 0, 1))
+	guard_lock_t old;
+	// Not an atomic read, doesn't establish a happens-before relationship, but
+	// if one is already established and we end up seeing an initialised state
+	// then it's a fast path, otherwise we'll do something more expensive than
+	// this test anyway...
+	if (INITIALISED == *INIT_PART(guard_object))
+		return 0;
+	// Spin trying to do the initialisation
+	for (;;)
 	{
-		if (1 == ((*guard_object) >> 56))
-		{
-			break;
+		// Loop trying to move the value of the guard from 0 (not
+		// locked, not initialised) to the locked-uninitialised
+		// position.
+		old = __sync_val_compare_and_swap(LOCK_PART(guard_object),
+		    INITIAL, LOCKED);
+		if (old == INITIAL) {
+			// Lock obtained.  If lock and init bit are
+			// in separate words, check for init race.
+			if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+				return 1;
+			if (INITIALISED != *INIT_PART(guard_object))
+				return 1;
+
+			// No need for a memory barrier here,
+			// see first comment.
+			*LOCK_PART(guard_object) = INITIAL;
+			return 0;
 		}
+		// If lock and init bit are in the same word, check again
+		// if we are done.
+		if (INIT_PART(guard_object) == LOCK_PART(guard_object) &&
+		    old == INITIALISED)
+			return 0;
+
+		assert(old == LOCKED);
+		// Another thread holds the lock.
+		// If lock and init bit are in different words, check
+		// if we are done before yielding and looping.
+		if (INIT_PART(guard_object) != LOCK_PART(guard_object) &&
+		    INITIALISED == *INIT_PART(guard_object))
+			return 0;
 		sched_yield();
 	}
-	// We have to test the guard again, in case another thread has performed
-	// the initialisation while we were trying to acquire the lock.
-	first_byte = (*guard_object) >> 56;
-	return (1 != first_byte);
 }
 
 /**
@@ -145,20 +166,28 @@
  * Releases the lock without marking the object as initialised.  This function
  * is called if initialising a static causes an exception to be thrown.
  */
-extern "C" void __cxa_guard_abort(int64_t *guard_object)
+extern "C" void __cxa_guard_abort(volatile guard_t *guard_object)
 {
-	int32_t *lock = low_32_bits(guard_object);
-	*lock = 0;
+	__attribute__((unused))
+	bool reset = __sync_bool_compare_and_swap(LOCK_PART(guard_object),
+	    LOCKED, INITIAL);
+	assert(reset);
 }
 /**
  * Releases the guard and marks the object as initialised.  This function is
  * called after successful initialisation of a static.
  */
-extern "C" void __cxa_guard_release(int64_t *guard_object)
+extern "C" void __cxa_guard_release(volatile guard_t *guard_object)
 {
-	// Set the first byte to 1
-	*guard_object |= ((int64_t)1) << 56;
-	__cxa_guard_abort(guard_object);
+	guard_lock_t old;
+	if (INIT_PART(guard_object) == LOCK_PART(guard_object))
+		old = LOCKED;
+	else
+		old = INITIAL;
+	__attribute__((unused))
+	bool reset = __sync_bool_compare_and_swap(INIT_PART(guard_object),
+	    old, INITIALISED);
+	assert(reset);
+	if (INIT_PART(guard_object) != LOCK_PART(guard_object))
+		*LOCK_PART(guard_object) = INITIAL;
 }
-
-#endif

Modified: trunk/contrib/libcxxrt/libelftc_dem_gnu3.c
===================================================================
--- trunk/contrib/libcxxrt/libelftc_dem_gnu3.c	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/libelftc_dem_gnu3.c	2016-02-28 21:26:57 UTC (rev 7451)
@@ -59,7 +59,7 @@
 
 enum type_qualifier {
 	TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,
-	TYPE_CST
+	TYPE_CST, TYPE_VEC
 };
 
 struct vector_type_qualifier {
@@ -397,6 +397,8 @@
 static int	cpp_demangle_read_encoding(struct cpp_demangle_data *);
 static int	cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
 static int	cpp_demangle_read_expression(struct cpp_demangle_data *);
+static int	cpp_demangle_read_expression_flat(struct cpp_demangle_data *,
+		    char **);
 static int	cpp_demangle_read_expression_binary(struct cpp_demangle_data *,
 		    const char *, size_t);
 static int	cpp_demangle_read_expression_unary(struct cpp_demangle_data *,
@@ -405,10 +407,15 @@
 		    const char *, size_t, const char *, size_t);
 static int	cpp_demangle_read_function(struct cpp_demangle_data *, int *,
 		    struct vector_type_qualifier *);
+static int	cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);
 static int	cpp_demangle_read_local_name(struct cpp_demangle_data *);
 static int	cpp_demangle_read_name(struct cpp_demangle_data *);
+static int	cpp_demangle_read_name_flat(struct cpp_demangle_data *,
+		    char**);
 static int	cpp_demangle_read_nested_name(struct cpp_demangle_data *);
 static int	cpp_demangle_read_number(struct cpp_demangle_data *, long *);
+static int	cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
+		    char **);
 static int	cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
 static int	cpp_demangle_read_offset(struct cpp_demangle_data *);
 static int	cpp_demangle_read_offset_number(struct cpp_demangle_data *);
@@ -422,6 +429,8 @@
 static int	cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
 static int	cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
 static int	cpp_demangle_read_type(struct cpp_demangle_data *, int);
+static int	cpp_demangle_read_type_flat(struct cpp_demangle_data *,
+		    char **);
 static int	cpp_demangle_read_uqname(struct cpp_demangle_data *);
 static int	cpp_demangle_read_v_offset(struct cpp_demangle_data *);
 static char	*decode_fp_to_double(const char *, size_t);
@@ -453,13 +462,22 @@
 	struct cpp_demangle_data ddata;
 	ssize_t org_len;
 	unsigned int limit;
-	char *rtn;
+	char *rtn = NULL;
 
 	if (org == NULL)
 		return (NULL);
 
+	org_len = strlen(org);
+	if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
+		if ((rtn = malloc(org_len + 19)) == NULL)
+			return (NULL);
+		snprintf(rtn, org_len + 19,
+		    "global constructors keyed to %s", org + 11);
+		return (rtn);
+	}
+
 	// Try demangling as a type for short encodings
-	if (((org_len = strlen(org)) < 2) || (org[0] != '_' || org[1] != 'Z' )) {
+	if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {
 		if (!cpp_demangle_data_init(&ddata, org))
 			return (NULL);
 		if (!cpp_demangle_read_type(&ddata, 0))
@@ -467,13 +485,6 @@
 		rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
 		goto clean;
 	}
-	if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
-		if ((rtn = malloc(org_len + 19)) == NULL)
-			return (NULL);
-		snprintf(rtn, org_len + 19,
-		    "global constructors keyed to %s", org + 11);
-		return (rtn);
-	}
 
 
 	if (!cpp_demangle_data_init(&ddata, org + 2))
@@ -598,19 +609,19 @@
 	fp = ddata->cur;
 	while (*ddata->cur != 'E')
 		++ddata->cur;
-	++ddata->cur;
 
 	if ((f = decoder(fp, ddata->cur - fp)) == NULL)
 		return (0);
 
 	rtn = 0;
-	if ((len = strlen(f)) > 0 &&
-	    cpp_demangle_push_str(ddata, f, len))
-		rtn = 1;
+	if ((len = strlen(f)) > 0)
+		rtn = cpp_demangle_push_str(ddata, f, len);
 
 	free(f);
 
-	return (0);
+	++ddata->cur;
+
+	return (rtn);
 }
 
 static int
@@ -655,6 +666,7 @@
 		return (0);
 
 	rtn = cpp_demangle_push_subst(ddata, str, str_len);
+
 	free(str);
 
 	return (rtn);
@@ -692,7 +704,8 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, "*", 1))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
@@ -703,7 +716,8 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, "&", 1))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
@@ -714,7 +728,8 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, " complex", 8))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
@@ -723,24 +738,27 @@
 			if (!cpp_demangle_push_str(ddata, " imaginary", 10))
 				goto clean;
 			if (type_str != NULL) {
-				if (!vector_str_push(&subst_v, " imaginary", 10))
+				if (!vector_str_push(&subst_v, " imaginary",
+				    10))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
 
 		case TYPE_EXT:
-			if (e_idx > v->ext_name.size - 1)
+			if (v->ext_name.size == 0 ||
+			    e_idx > v->ext_name.size - 1)
 				goto clean;
-			if ((e_len = strlen(v->ext_name.container[e_idx])) == 0)
+			if ((e_len = strlen(v->ext_name.container[e_idx])) ==
+			    0)
 				goto clean;
-			if ((buf = malloc(sizeof(char) * (e_len + 1))) == NULL)
+			if ((buf = malloc(e_len + 2)) == NULL)
 				goto clean;
+			snprintf(buf, e_len + 2, " %s",
+			    v->ext_name.container[e_idx]);
 
-			memcpy(buf, " ", 1);
-			memcpy(buf + 1, v->ext_name.container[e_idx], e_len);
-
 			if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) {
 				free(buf);
 				goto clean;
@@ -752,7 +770,8 @@
 					free(buf);
 					goto clean;
 				}
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v)) {
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v)) {
 					free(buf);
 					goto clean;
 				}
@@ -767,7 +786,8 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, " restrict", 9))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
@@ -778,7 +798,8 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, " volatile", 9))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
@@ -789,11 +810,42 @@
 			if (type_str != NULL) {
 				if (!vector_str_push(&subst_v, " const", 6))
 					goto clean;
-				if (!cpp_demangle_push_subst_v(ddata, &subst_v))
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v))
 					goto clean;
 			}
 			break;
 
+		case TYPE_VEC:
+			if (v->ext_name.size == 0 ||
+			    e_idx > v->ext_name.size - 1)
+				goto clean;
+			if ((e_len = strlen(v->ext_name.container[e_idx])) ==
+			    0)
+				goto clean;
+			if ((buf = malloc(e_len + 12)) == NULL)
+				goto clean;
+			snprintf(buf, e_len + 12, " __vector(%s)",
+			    v->ext_name.container[e_idx]);
+			if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) {
+				free(buf);
+				goto clean;
+			}
+			if (type_str != NULL) {
+				if (!vector_str_push(&subst_v, buf,
+				    e_len + 11)) {
+					free(buf);
+					goto clean;
+				}
+				if (!cpp_demangle_push_subst_v(ddata,
+				    &subst_v)) {
+					free(buf);
+					goto clean;
+				}
+			}
+			free(buf);
+			++e_idx;
+			break;
 		};
 		--idx;
 	}
@@ -944,10 +996,14 @@
 
 	switch (*ddata->cur) {
 	case 'b':
+		if (*(ddata->cur + 2) != 'E')
+			return (0);
 		switch (*(++ddata->cur)) {
 		case '0':
+			ddata->cur += 2;
 			return (cpp_demangle_push_str(ddata, "false", 5));
 		case '1':
+			ddata->cur += 2;
 			return (cpp_demangle_push_str(ddata, "true", 4));
 		default:
 			return (0);
@@ -996,7 +1052,8 @@
 			++ddata->cur;
 		}
 		++ddata->cur;
-		return (cpp_demangle_push_str(ddata, num, ddata->cur - num));
+		return (cpp_demangle_push_str(ddata, num,
+		    ddata->cur - num - 1));
 
 	default:
 		return (0);
@@ -1288,6 +1345,38 @@
 }
 
 static int
+cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)
+{
+	struct vector_str *output;
+	size_t i, p_idx, idx, exp_len;
+	char *exp;
+
+	output = ddata->push_head > 0 ? &ddata->output_tmp :
+	    &ddata->output;
+
+	p_idx = output->size;
+
+	if (!cpp_demangle_read_expression(ddata))
+		return (0);
+
+	if ((exp = vector_str_substr(output, p_idx, output->size - 1,
+	    &exp_len)) == NULL)
+		return (0);
+
+	idx = output->size;
+	for (i = p_idx; i < idx; ++i) {
+		if (!vector_str_pop(output)) {
+			free(exp);
+			return (0);
+		}
+	}
+
+	*str = exp;
+
+	return (1);
+}
+
+static int
 cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,
     const char *name, size_t len)
 {
@@ -1416,6 +1505,9 @@
 static int
 cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
 {
+	char *name, *type, *num_str;
+	long offset;
+	int rtn;
 
 	if (ddata == NULL || *ddata->cur == '\0')
 		return (0);
@@ -1422,6 +1514,56 @@
 
 	/* special name */
 	switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
+	case SIMPLE_HASH('G', 'A'):
+		if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		return (cpp_demangle_read_encoding(ddata));
+
+	case SIMPLE_HASH('G', 'R'):
+		if (!cpp_demangle_push_str(ddata, "reference temporary #", 21))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		if (!cpp_demangle_read_name_flat(ddata, &name))
+			return (0);
+		rtn = 0;
+		if (!cpp_demangle_read_number_as_string(ddata, &num_str))
+			goto clean1;
+		if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str)))
+			goto clean2;
+		if (!cpp_demangle_push_str(ddata, " for ", 5))
+			goto clean2;
+		if (!cpp_demangle_push_str(ddata, name, strlen(name)))
+			goto clean2;
+		rtn = 1;
+	clean2:
+		free(num_str);
+	clean1:
+		free(name);
+		return (rtn);
+
+	case SIMPLE_HASH('G', 'T'):
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		switch (*ddata->cur) {
+		case 'n':
+			if (!cpp_demangle_push_str(ddata,
+			    "non-transaction clone for ", 26))
+				return (0);
+		case 't':
+		default:
+			if (!cpp_demangle_push_str(ddata,
+			    "transaction clone for ", 22))
+				return (0);
+		}
+		++ddata->cur;
+		return (cpp_demangle_read_encoding(ddata));
+
 	case SIMPLE_HASH('G', 'V'):
 		/* sentry object for 1 time init */
 		if (!cpp_demangle_push_str(ddata, "guard variable for ", 20))
@@ -1443,14 +1585,49 @@
 			return (0);
 		return (cpp_demangle_read_encoding(ddata));
 
+	case SIMPLE_HASH('T', 'C'):
+		/* construction vtable */
+		if (!cpp_demangle_push_str(ddata, "construction vtable for ",
+		    24))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		if (!cpp_demangle_read_type_flat(ddata, &type))
+			return (0);
+		rtn = 0;
+		if (!cpp_demangle_read_number(ddata, &offset))
+			goto clean3;
+		if (*ddata->cur++ != '_')
+			goto clean3;
+		if (!cpp_demangle_read_type(ddata, 0))
+			goto clean3;
+		if (!cpp_demangle_push_str(ddata, "-in-", 4))
+			goto clean3;
+		if (!cpp_demangle_push_str(ddata, type, strlen(type)))
+			goto clean3;
+		rtn = 1;
+	clean3:
+		free(type);
+		return (rtn);
+
 	case SIMPLE_HASH('T', 'D'):
 		/* typeinfo common proxy */
 		break;
 
+	case SIMPLE_HASH('T', 'F'):
+		/* typeinfo fn */
+		if (!cpp_demangle_push_str(ddata, "typeinfo fn for ", 16))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		return (cpp_demangle_read_type(ddata, 0));
+
 	case SIMPLE_HASH('T', 'h'):
 		/* virtual function non-virtual override thunk */
-		if (cpp_demangle_push_str(ddata,
-		    "virtual function non-virtual override ", 38) == 0)
+		if (!cpp_demangle_push_str(ddata,
+		    "virtual function non-virtual override ", 38))
 			return (0);
 		ddata->cur += 2;
 		if (*ddata->cur == '\0')
@@ -1459,17 +1636,42 @@
 			return (0);
 		return (cpp_demangle_read_encoding(ddata));
 
+	case SIMPLE_HASH('T', 'H'):
+		/* TLS init function */
+		if (!cpp_demangle_push_str(ddata, "TLS init function for ",
+		    22))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		break;
+
 	case SIMPLE_HASH('T', 'I'):
 		/* typeinfo structure */
-		/* FALLTHROUGH */
+		if (!cpp_demangle_push_str(ddata, "typeinfo for ", 13))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		return (cpp_demangle_read_type(ddata, 0));
+
+	case SIMPLE_HASH('T', 'J'):
+		/* java class */
+		if (!cpp_demangle_push_str(ddata, "java Class for ", 15))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		return (cpp_demangle_read_type(ddata, 0));
+
 	case SIMPLE_HASH('T', 'S'):
 		/* RTTI name (NTBS) */
-		if (!cpp_demangle_push_str(ddata, "typeinfo for ", 14))
+		if (!cpp_demangle_push_str(ddata, "typeinfo name for ", 18))
 			return (0);
 		ddata->cur += 2;
 		if (*ddata->cur == '\0')
 			return (0);
-		return (cpp_demangle_read_type(ddata, 1));
+		return (cpp_demangle_read_type(ddata, 0));
 
 	case SIMPLE_HASH('T', 'T'):
 		/* VTT table */
@@ -1476,7 +1678,9 @@
 		if (!cpp_demangle_push_str(ddata, "VTT for ", 8))
 			return (0);
 		ddata->cur += 2;
-		return (cpp_demangle_read_type(ddata, 1));
+		if (*ddata->cur == '\0')
+			return (0);
+		return (cpp_demangle_read_type(ddata, 0));
 
 	case SIMPLE_HASH('T', 'v'):
 		/* virtual function virtual override thunk */
@@ -1497,7 +1701,17 @@
 		ddata->cur += 2;
 		if (*ddata->cur == '\0')
 			return (0);
-		return (cpp_demangle_read_type(ddata, 1));
+		return (cpp_demangle_read_type(ddata, 0));
+
+	case SIMPLE_HASH('T', 'W'):
+		/* TLS wrapper function */
+		if (!cpp_demangle_push_str(ddata, "TLS wrapper function for ",
+		    25))
+			return (0);
+		ddata->cur += 2;
+		if (*ddata->cur == '\0')
+			return (0);
+		break;
 	};
 
 	return (cpp_demangle_read_name(ddata));
@@ -1615,6 +1829,38 @@
 }
 
 static int
+cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)
+{
+	struct vector_str *output;
+	size_t i, p_idx, idx, name_len;
+	char *name;
+
+	output = ddata->push_head > 0 ? &ddata->output_tmp :
+	    &ddata->output;
+
+	p_idx = output->size;
+
+	if (!cpp_demangle_read_name(ddata))
+		return (0);
+
+	if ((name = vector_str_substr(output, p_idx, output->size - 1,
+	    &name_len)) == NULL)
+		return (0);
+
+	idx = output->size;
+	for (i = p_idx; i < idx; ++i) {
+		if (!vector_str_pop(output)) {
+			free(name);
+			return (0);
+		}
+	}
+
+	*str = name;
+
+	return (1);
+}
+
+static int
 cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)
 {
 	struct vector_str *output, v;
@@ -1740,6 +1986,24 @@
 }
 
 static int
+cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)
+{
+	long n;
+
+	if (!cpp_demangle_read_number(ddata, &n)) {
+		*str = NULL;
+		return (0);
+	}
+
+	if (asprintf(str, "%ld", n) < 0) {
+		*str = NULL;
+		return (0);
+	}
+
+	return (1);
+}
+
+static int
 cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)
 {
 
@@ -1868,11 +2132,20 @@
 cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
 {
 	long len;
+	int err;
 
 	if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||
-	    len <= 0 || cpp_demangle_push_str(ddata, ddata->cur, len) == 0)
+	    len <= 0)
 		return (0);
 
+	if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))
+		err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21);
+	else
+		err = cpp_demangle_push_str(ddata, ddata->cur, len);
+
+	if (err == 0)
+		return (0);
+
 	assert(ddata->output.size > 0);
 	if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0)
 		ddata->last_sname =
@@ -2054,7 +2327,7 @@
 	free(subst_str);
 	vector_str_dest(&v);
 
-	return (1);
+	return (rtn);
 }
 
 static int
@@ -2220,7 +2493,7 @@
 	size_t p_idx, type_str_len;
 	int extern_c, is_builtin;
 	long len;
-	char *type_str;
+	char *type_str, *exp_str, *num_str;
 
 	if (ddata == NULL)
 		return (0);
@@ -2262,7 +2535,7 @@
 	extern_c = 0;
 	is_builtin = 1;
 	p_idx = output->size;
-	type_str = NULL;
+	type_str = exp_str = num_str = NULL;
 again:
 	/* builtin type */
 	switch (*ddata->cur) {
@@ -2308,6 +2581,82 @@
 		++ddata->cur;
 		goto rtn;
 
+	case 'D':
+		++ddata->cur;
+		switch (*ddata->cur) {
+		case 'd':
+			/* IEEE 754r decimal floating point (64 bits) */
+			if (!cpp_demangle_push_str(ddata, "decimal64", 9))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'e':
+			/* IEEE 754r decimal floating point (128 bits) */
+			if (!cpp_demangle_push_str(ddata, "decimal128", 10))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'f':
+			/* IEEE 754r decimal floating point (32 bits) */
+			if (!cpp_demangle_push_str(ddata, "decimal32", 9))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'h':
+			/* IEEE 754r half-precision floating point (16 bits) */
+			if (!cpp_demangle_push_str(ddata, "half", 4))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'i':
+			/* char32_t */
+			if (!cpp_demangle_push_str(ddata, "char32_t", 8))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'n':
+			/* std::nullptr_t (i.e., decltype(nullptr)) */
+			if (!cpp_demangle_push_str(ddata, "decltype(nullptr)",
+			    17))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 's':
+			/* char16_t */
+			if (!cpp_demangle_push_str(ddata, "char16_t", 8))
+				goto clean;
+			++ddata->cur;
+			break;
+		case 'v':
+			/* gcc vector_size extension. */
+			++ddata->cur;
+			if (*ddata->cur == '_') {
+				++ddata->cur;
+				if (!cpp_demangle_read_expression_flat(ddata,
+				    &exp_str))
+					goto clean;
+				if (!vector_str_push(&v.ext_name, exp_str,
+				    strlen(exp_str)))
+					goto clean;
+			} else {
+				if (!cpp_demangle_read_number_as_string(ddata,
+				    &num_str))
+					goto clean;
+				if (!vector_str_push(&v.ext_name, num_str,
+				    strlen(num_str)))
+					goto clean;
+			}
+			if (*ddata->cur != '_')
+				goto clean;
+			++ddata->cur;
+			if (!vector_type_qualifier_push(&v, TYPE_VEC))
+				goto clean;
+			goto again;
+		default:
+			goto clean;
+		}
+		goto rtn;
+
 	case 'e':
 		/* long double */
 		if (!cpp_demangle_push_str(ddata, "long double", 11))
@@ -2402,7 +2751,7 @@
 
 	case 'o':
 		/* unsigned __int128 */
-		if (!cpp_demangle_push_str(ddata, "unsigned _;int128", 17))
+		if (!cpp_demangle_push_str(ddata, "unsigned __int128", 17))
 			goto clean;
 		++ddata->cur;
 		goto rtn;
@@ -2473,6 +2822,8 @@
 		if (!vector_str_push(&v.ext_name, ddata->cur, len))
 			return (0);
 		ddata->cur += len;
+		if (!vector_type_qualifier_push(&v, TYPE_EXT))
+			goto clean;
 		goto again;
 
 	case 'v':
@@ -2537,6 +2888,8 @@
 		goto clean;
 
 	free(type_str);
+	free(exp_str);
+	free(num_str);
 	vector_type_qualifier_dest(&v);
 
 	if (ddata->push_head > 0) {
@@ -2568,11 +2921,45 @@
 	return (1);
 clean:
 	free(type_str);
+	free(exp_str);
+	free(num_str);
 	vector_type_qualifier_dest(&v);
 
 	return (0);
 }
 
+static int
+cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)
+{
+	struct vector_str *output;
+	size_t i, p_idx, idx, type_len;
+	char *type;
+
+	output = ddata->push_head > 0 ? &ddata->output_tmp :
+	    &ddata->output;
+
+	p_idx = output->size;
+
+	if (!cpp_demangle_read_type(ddata, 0))
+		return (0);
+
+	if ((type = vector_str_substr(output, p_idx, output->size - 1,
+	    &type_len)) == NULL)
+		return (0);
+
+	idx = output->size;
+	for (i = p_idx; i < idx; ++i) {
+		if (!vector_str_pop(output)) {
+			free(type);
+			return (0);
+		}
+	}
+
+	*str = type;
+
+	return (1);
+}
+
 /*
  * read unqualified-name, unqualified name are operator-name, ctor-dtor-name,
  * source-name
@@ -2996,10 +3383,43 @@
 	if (ELFTC_ISDIGIT(*ddata->cur) != 0)
 		return (cpp_demangle_read_sname(ddata));
 
+	/* local source name */
+	if (*ddata->cur == 'L')
+		return (cpp_demangle_local_source_name(ddata));
+
 	return (1);
 }
 
+/*
+ * Read local source name.
+ *
+ * References:
+ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
+ *   http://gcc.gnu.org/viewcvs?view=rev&revision=124467
+ */
 static int
+cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)
+{
+	/* L */
+	if (ddata == NULL || *ddata->cur != 'L')
+		return (0);
+	++ddata->cur;
+
+	/* source name */
+	if (!cpp_demangle_read_sname(ddata))
+		return (0);
+
+	/* discriminator */
+	if (*ddata->cur == '_') {
+		++ddata->cur;
+		while (ELFTC_ISDIGIT(*ddata->cur) != 0)
+			++ddata->cur;
+	}
+
+	return (1);
+}
+
+static int
 cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)
 {
 

Modified: trunk/contrib/libcxxrt/memory.cc
===================================================================
--- trunk/contrib/libcxxrt/memory.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/memory.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -36,15 +36,9 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include "stdexcept.h"
+#include "atomic.h"
 
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
 
-#if !__has_builtin(__sync_swap)
-#define __sync_swap __sync_lock_test_and_set
-#endif
-
 namespace std
 {
 	struct nothrow_t {};
@@ -67,8 +61,13 @@
 	__attribute__((weak))
 	new_handler set_new_handler(new_handler handler)
 	{
-		return __sync_swap(&new_handl, handler);
+		return ATOMIC_SWAP(&new_handl, handler);
 	}
+	__attribute__((weak))
+	new_handler get_new_handler(void)
+	{
+		return ATOMIC_LOAD(&new_handl);
+	}
 }
 
 
@@ -75,12 +74,17 @@
 __attribute__((weak))
 void* operator new(size_t size)
 {
+	if (0 == size)
+	{
+		size = 1;
+	}
 	void * mem = malloc(size);
 	while (0 == mem)
 	{
-		if (0 != new_handl)
+		new_handler h = std::get_new_handler();
+		if (0 != h)
 		{
-			new_handl();
+			h();
 		}
 		else
 		{
@@ -95,35 +99,21 @@
 __attribute__((weak))
 void* operator new(size_t size, const std::nothrow_t &) throw()
 {
-	void *mem = malloc(size);
-	while (0 == mem)
-	{
-		if (0 != new_handl)
-		{
-			try
-			{
-				new_handl();
-			}
-			catch (...)
-			{
-				// nothrow operator new should return NULL in case of
-				// std::bad_alloc exception in new handler
-				return NULL;
-			}
-		}
-		else
-		{
-			return NULL;
-		}
-		mem = malloc(size);
+	try {
+		return :: operator new(size);
+	} catch (...) {
+		// nothrow operator new should return NULL in case of
+		// std::bad_alloc exception in new handler
+		return NULL;
 	}
-
-	return mem;
 }
 
 
 __attribute__((weak))
 void operator delete(void * ptr)
+#if __cplusplus < 201000L
+throw()
+#endif
 {
 	free(ptr);
 }
@@ -131,6 +121,9 @@
 
 __attribute__((weak))
 void * operator new[](size_t size)
+#if __cplusplus < 201000L
+throw(std::bad_alloc)
+#endif
 {
 	return ::operator new(size);
 }
@@ -137,8 +130,24 @@
 
 
 __attribute__((weak))
-void operator delete[](void * ptr) throw()
+void * operator new[](size_t size, const std::nothrow_t &) throw()
 {
+	try {
+		return ::operator new[](size);
+	} catch (...) {
+		// nothrow operator new should return NULL in case of
+		// std::bad_alloc exception in new handler
+		return NULL;
+	}
+}
+
+
+__attribute__((weak))
+void operator delete[](void * ptr)
+#if __cplusplus < 201000L
+throw()
+#endif
+{
 	::operator delete(ptr);
 }
 

Modified: trunk/contrib/libcxxrt/stdexcept.cc
===================================================================
--- trunk/contrib/libcxxrt/stdexcept.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/stdexcept.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -82,5 +82,18 @@
 	return "std::bad_typeid";
 }
 
+bad_array_new_length::bad_array_new_length() throw() {}
+bad_array_new_length::~bad_array_new_length() {}
+bad_array_new_length::bad_array_new_length(const bad_array_new_length&) throw() {}
+bad_array_new_length& bad_array_new_length::operator=(const bad_array_new_length&) throw()
+{
+	return *this;
+}
+
+const char* bad_array_new_length::what() const throw()
+{
+	return "std::bad_array_new_length";
+}
+
 } // namespace std
 

Modified: trunk/contrib/libcxxrt/stdexcept.h
===================================================================
--- trunk/contrib/libcxxrt/stdexcept.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/stdexcept.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -81,6 +81,15 @@
 		virtual const char* what() const throw();
 	};
 
+	class bad_array_new_length: public bad_alloc
+	{
+	public:
+		bad_array_new_length() throw();
+		bad_array_new_length(const bad_array_new_length&) throw();
+		bad_array_new_length& operator=(const bad_array_new_length&) throw();
+		virtual ~bad_array_new_length();
+		virtual const char *what() const throw();
+	};
 
 
 } // namespace std

Modified: trunk/contrib/libcxxrt/typeinfo.cc
===================================================================
--- trunk/contrib/libcxxrt/typeinfo.cc	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/typeinfo.cc	2016-02-28 21:26:57 UTC (rev 7451)
@@ -86,7 +86,18 @@
 	if (NULL != demangled)
 	{
 		size_t len = strlen(demangled);
-		buf = (char*)realloc(buf, len+1);
+		if (buf == NULL)
+		{
+			if (n)
+			{
+				*n = len;
+			}
+			return demangled;
+		}
+		if (*n < len+1)
+		{
+			buf = static_cast<char*>(realloc(buf, len+1));
+		}
 		if (0 != buf)
 		{
 			memcpy(buf, demangled, len);

Modified: trunk/contrib/libcxxrt/typeinfo.h
===================================================================
--- trunk/contrib/libcxxrt/typeinfo.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/typeinfo.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -70,6 +70,14 @@
 		 */
 		public:
 		/**
+		 * Returns true if this is some pointer type, false otherwise.
+		 */
+		virtual bool __is_pointer_p() const { return false; }
+		/**
+		 * Returns true if this is some function type, false otherwise.
+		 */
+		virtual bool __is_function_p() const { return false; }
+		/**
 		 * Catch function.  Allows external libraries to implement
 		 * their own basic types.  This is used, for example, in the
 		 * GNUstep Objective-C runtime to allow Objective-C types to be
@@ -95,14 +103,6 @@
 		{
 			return false;
 		}
-		/**
-		 * Returns true if this is some pointer type, false otherwise.
-		 */
-		virtual bool __is_pointer_p() const { return false; }
-		/**
-		 * Returns true if this is some function type, false otherwise.
-		 */
-		virtual bool __is_function_p() const { return false; }
 	};
 }
 
@@ -284,7 +284,6 @@
 			/** Pointer is a pointer to a member of an incomplete class. */
 			__incomplete_class_mask = 0x10
 		};
-		virtual bool __is_pointer_p() const { return true; }
 		virtual bool __do_catch(const type_info *thrown_type,
 		                        void **thrown_object,
 		                        unsigned outer) const;
@@ -296,6 +295,7 @@
 	struct __pointer_type_info : public __pbase_type_info
 	{
 		virtual ~__pointer_type_info();
+		virtual bool __is_pointer_p() const { return true; }
 	};
 
 	/**

Modified: trunk/contrib/libcxxrt/unwind-arm.h
===================================================================
--- trunk/contrib/libcxxrt/unwind-arm.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind-arm.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -36,6 +36,8 @@
 	_URC_FATAL_PHASE1_ERROR = _URC_FAILURE
 } _Unwind_Reason_Code;
 
+typedef int _Unwind_Action;
+
 typedef uint32_t _Unwind_State;
 #ifdef __clang__
 static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME  = 0;
@@ -218,6 +220,6 @@
 			break;\
 		}\
 	}\
-	_Unwind_SetGR (context, 12, (unsigned long)exceptionObject);\
+	_Unwind_SetGR (context, 12, reinterpret_cast<unsigned long>(exceptionObject));\
 
 #define CALL_PERSONALITY_FUNCTION(name) name(state,exceptionObject,context)

Modified: trunk/contrib/libcxxrt/unwind-itanium.h
===================================================================
--- trunk/contrib/libcxxrt/unwind-itanium.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind-itanium.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -80,7 +80,7 @@
     _Unwind_Exception_Cleanup_Fn exception_cleanup;
     unsigned long private_1;
     unsigned long private_2;
-  } __attribute__((__aligned__));
+  } ;
 
 extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
 extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,

Modified: trunk/contrib/libcxxrt/unwind.h
===================================================================
--- trunk/contrib/libcxxrt/unwind.h	2016-02-27 13:52:54 UTC (rev 7450)
+++ trunk/contrib/libcxxrt/unwind.h	2016-02-28 21:26:57 UTC (rev 7451)
@@ -27,7 +27,7 @@
 extern "C" {
 #endif
 
-#ifdef __arm__
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
 #include "unwind-arm.h"
 #else
 #include "unwind-itanium.h"



More information about the Midnightbsd-cvs mailing list