Two changes: 1) I still didn't have the ABI correct to match the gcc-4.2 std::string under the exception classes. I think the changes to stdexcept.cpp have got that down now. 2) On Apple platforms I'm seeing visibility bugs in applications with respect to type_info's being hidden. This is causing dynamic_cast to malfunction because there are multiple type_info's running around for one type within an application, making dynamic_cast believe that one type is actually multiple types. As a stop gap measure I'm trying to detect this error, print out an error message, but continue with the most likely desired result. This is all under __APPLE__. This behavior can be expanded to other platforms if desired.
llvm-svn: 164809
This commit is contained in:
		
							parent
							
								
									21b51062db
								
							
						
					
					
						commit
						2d0352cbf8
					
				| 
						 | 
				
			
			@ -9,6 +9,10 @@
 | 
			
		|||
 | 
			
		||||
#include "private_typeinfo.h"
 | 
			
		||||
 | 
			
		||||
#if __APPLE__
 | 
			
		||||
#include <sys/syslog.h>
 | 
			
		||||
#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)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<std::ptrdiff_t>(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<std::ptrdiff_t>(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<const char*>(::operator new(len + 1 + offset));
 | 
			
		||||
    _Rep_base* c = (_Rep_base*)str_;
 | 
			
		||||
    c->len = c->cap = len;
 | 
			
		||||
    str_ += offset;
 | 
			
		||||
    count() = 0;
 | 
			
		||||
    std::strcpy(const_cast<char*>(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<char*>(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<char*>(str_ - offset));
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue