diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp index 04ce90133767..d15b952b9ecb 100644 --- a/libcxxabi/src/private_typeinfo.cpp +++ b/libcxxabi/src/private_typeinfo.cpp @@ -9,6 +9,10 @@ #include "private_typeinfo.h" +#if __APPLE__ +#include +#endif + namespace __cxxabiv1 { @@ -437,6 +441,19 @@ __dynamic_cast(const void* static_ptr, info.number_of_dst_type = 1; // Do the search dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path); +#if __APPLE__ + // The following if should always be false because we should definitely + // find (static_ptr, static_type), either on a public or private path + if (info.path_dst_ptr_to_static_ptr == unknown) + { + // We get here only if there is some kind of visibility problem + // in client code. + syslog(LOG_ERR, "dynamic_cast error 1: There is a hidden visibility " + "problem associated with the type_info's of %s" + " and/or %s.\n", static_type->name(), dynamic_type->name()); + info.path_dst_ptr_to_static_ptr = public_path; + } +#endif // __APPLE__ // Query the search. if (info.path_dst_ptr_to_static_ptr == public_path) dst_ptr = dynamic_ptr; @@ -445,6 +462,18 @@ __dynamic_cast(const void* static_ptr, { // Not using giant short cut. Do the search dynamic_type->search_below_dst(&info, dynamic_ptr, public_path); + #if __APPLE__ + // The following if should always be false because we should definitely + // find (static_ptr, static_type), either on a public or private path + if (info.path_dst_ptr_to_static_ptr == unknown && + info.path_dynamic_ptr_to_static_ptr == unknown) + { + syslog(LOG_ERR, "dynamic_cast error 2: There is a hidden visibility " + "problem associated with the type_info's of %s" + " and/or %s and/or %s.\n", static_type->name(), dynamic_type->name(), + dst_type->name()); + } +#endif // __APPLE__ // Query the search. switch (info.number_to_static_ptr) { diff --git a/libcxxabi/src/stdexcept.cpp b/libcxxabi/src/stdexcept.cpp index 4f175a27ef36..de859db45811 100644 --- a/libcxxabi/src/stdexcept.cpp +++ b/libcxxabi/src/stdexcept.cpp @@ -31,13 +31,18 @@ class __libcpp_nmstr private: const char* str_; - typedef std::size_t unused_t; - typedef std::ptrdiff_t count_t; + typedef int count_t; - static const std::ptrdiff_t offset = static_cast(2*sizeof(unused_t) + - sizeof(count_t)); + struct _Rep_base + { + std::size_t len; + std::size_t cap; + count_t count; + }; - count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));} + static const std::ptrdiff_t offset = static_cast(sizeof(_Rep_base)); + + count_t& count() const _NOEXCEPT {return ((_Rep_base*)(str_ - offset))->count;} #if __APPLE__ static @@ -70,9 +75,9 @@ public: __libcpp_nmstr::__libcpp_nmstr(const char* msg) { std::size_t len = strlen(msg); - str_ = new char[len + 1 + offset]; - unused_t* c = (unused_t*)str_; - c[0] = c[1] = len; + str_ = static_cast(::operator new(len + 1 + offset)); + _Rep_base* c = (_Rep_base*)str_; + c->len = c->cap = len; str_ += offset; count() = 0; std::strcpy(const_cast(c_str()), msg); @@ -101,7 +106,9 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s) if (p != get_gcc_empty_string_storage()) #endif if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), count_t(-1)) < 0) - delete [] (p-offset); + { + ::operator delete(const_cast(p-offset)); + } return *this; } @@ -112,7 +119,9 @@ __libcpp_nmstr::~__libcpp_nmstr() if (str_ != get_gcc_empty_string_storage()) #endif if (__sync_add_and_fetch(&count(), count_t(-1)) < 0) - delete [] (str_ - offset); + { + ::operator delete(const_cast(str_ - offset)); + } } }