[cfe-commits] [libcxxabi] r164809 - in /libcxxabi/trunk/src: private_typeinfo.cpp stdexcept.cpp

Howard Hinnant hhinnant at apple.com
Thu Sep 27 17:05:34 PDT 2012


Author: hhinnant
Date: Thu Sep 27 19:05:34 2012
New Revision: 164809

URL: http://llvm.org/viewvc/llvm-project?rev=164809&view=rev
Log:
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.

Modified:
    libcxxabi/trunk/src/private_typeinfo.cpp
    libcxxabi/trunk/src/stdexcept.cpp

Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=164809&r1=164808&r2=164809&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Thu Sep 27 19:05:34 2012
@@ -9,6 +9,10 @@
 
 #include "private_typeinfo.h"
 
+#if __APPLE__
+#include <sys/syslog.h>
+#endif
+
 namespace __cxxabiv1
 {
 
@@ -437,6 +441,19 @@
         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 @@
     {
         // 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)
         {

Modified: libcxxabi/trunk/src/stdexcept.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/stdexcept.cpp?rev=164809&r1=164808&r2=164809&view=diff
==============================================================================
--- libcxxabi/trunk/src/stdexcept.cpp (original)
+++ libcxxabi/trunk/src/stdexcept.cpp Thu Sep 27 19:05:34 2012
@@ -31,13 +31,18 @@
 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;
+    };
+
+    static const std::ptrdiff_t offset = static_cast<std::ptrdiff_t>(sizeof(_Rep_base));
 
-    count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));}
+    count_t& count() const _NOEXCEPT {return ((_Rep_base*)(str_ - offset))->count;}
 
 #if __APPLE__
     static
@@ -70,9 +75,9 @@
 __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 @@
     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 @@
     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));
+        }
 }
 
 }





More information about the cfe-commits mailing list