[cfe-commits] [libcxxabi] r148666 - in /libcxxabi/trunk/src: cxa_personality.cpp private_typeinfo.cpp private_typeinfo.h

Howard Hinnant hhinnant at apple.com
Sun Jan 22 13:47:40 PST 2012


Author: hhinnant
Date: Sun Jan 22 15:47:40 2012
New Revision: 148666

URL: http://llvm.org/viewvc/llvm-project?rev=148666&view=rev
Log:
Getting started on matching a thrown exception to a catch clause, and setting the adjusted pointer to the caught object appearing in the catch clause.

Modified:
    libcxxabi/trunk/src/cxa_personality.cpp
    libcxxabi/trunk/src/private_typeinfo.cpp
    libcxxabi/trunk/src/private_typeinfo.h

Modified: libcxxabi/trunk/src/cxa_personality.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_personality.cpp?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_personality.cpp (original)
+++ libcxxabi/trunk/src/cxa_personality.cpp Sun Jan 22 15:47:40 2012
@@ -14,6 +14,7 @@
 
 #include "unwind.h"
 #include "cxa_exception.hpp"
+#include "private_typeinfo.h"
 #include <typeinfo>
 #include <stdlib.h>
 #include <assert.h>
@@ -219,6 +220,8 @@
     return classInfo - typeOffset;
 }
 
+static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
+
 /// Deals with Dwarf actions matching our type infos 
 /// (OurExceptionType_t instances). Returns whether or not a dwarf emitted 
 /// action matches the supplied exception type. If such a match succeeds, 
@@ -240,7 +243,12 @@
                   _Unwind_Exception* unwind_exception, uint8_t ttypeEncoding)
 {
     __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
-    const std::type_info* excpType = exception_header->exceptionType;
+    void* thrown_object =
+        unwind_exception->exception_class == kOurDependentExceptionClass ?
+            ((__cxa_dependent_exception*)exception_header)->primaryException :
+            exception_header + 1;
+    const __shim_type_info* excpType =
+        static_cast<const __shim_type_info*>(exception_header->exceptionType);
     const uint8_t* actionPos = (uint8_t*)actionEntry;
     while (true)
     {
@@ -255,14 +263,17 @@
         {
             const uint8_t* TTypeEntry = getTTypeEntry(typeOffset, classInfo,
                                                       ttypeEncoding);
-            const std::type_info* catchType =
-                       (const std::type_info*)readEncodedPointer(&TTypeEntry,
+            const __shim_type_info* catchType =
+                       (const __shim_type_info*)readEncodedPointer(&TTypeEntry,
                                                                  ttypeEncoding);
+            void* adjustedPtr = thrown_object;
             // catchType == 0 -> catch (...)
-            if (catchType == 0 || excpType == catchType)
+            if (catchType == 0 || catchType->can_catch(excpType, adjustedPtr))
             {
                 exception_header->handlerSwitchValue = typeOffset;
-                exception_header->actionRecord = SactionPos;
+                exception_header->actionRecord = SactionPos;  // unnecessary?
+                // used by __cxa_get_exception_ptr and __cxa_begin_catch
+                exception_header->adjustedPtr = adjustedPtr;
                 return true;
             }
         }
@@ -289,9 +300,6 @@
     __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
     const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
     exception_header->languageSpecificData = lsda;
-    // set adjustedPtr!  __cxa_get_exception_ptr and __cxa_begin_catch use it.
-    // TODO:  Put it where it is supposed to be and adjust it properly
-    exception_header->adjustedPtr = unwind_exception+1;
     if (lsda)
     {
         // Get the current instruction pointer and offset it before next

Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Sun Jan 22 15:47:40 2012
@@ -198,6 +198,42 @@
     __pointee->display();
 }
 
+// can_catch
+
+// A handler is a match for an exception object of type E if
+//   * The handler is of type cv T or cv T& and E and T are the same type
+//     (ignoring the top-level cv-qualifiers), or
+//   * the handler is of type cv T or cv T& and T is an unambiguous public
+//     base class of E, or
+//   * the handler is of type cv1 T* cv2 and E is a pointer type that can be
+//     converted to the type of the handler by either or both of
+//     * a standard pointer conversion (4.10) not involving conversions to
+//       pointers to private or protected or ambiguous classes
+//     * a qualification conversion
+//   * the handler is a pointer or pointer to member type and E is std::nullptr_t.
+
+// adjustedPtr:
+// 
+// catch (A& a) : adjustedPtr == &a
+// catch (A* a) : adjustedPtr == a
+// catch (A** a) : adjustedPtr == a
+// 
+// catch (D2& d2) : adjustedPtr == &d2  (d2 is base class of thrown object)
+// catch (D2* d2) : adjustedPtr == d2
+// catch (D2*& d2) : adjustedPtr == d2
+// 
+// catch (...) : adjustedPtr == & of the exception
+
+// TODO:  can_catch looks similar to search_above_dst.  Reuse?
+
+bool
+__shim_type_info::can_catch(const __shim_type_info* thrown_type,
+                            void*&) const
+{
+    return this == thrown_type;
+}
+
+
 #pragma GCC visibility pop
 #pragma GCC visibility push(default)
 

Modified: libcxxabi/trunk/src/private_typeinfo.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.h?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.h (original)
+++ libcxxabi/trunk/src/private_typeinfo.h Sun Jan 22 15:47:40 2012
@@ -24,6 +24,7 @@
 public:
     virtual ~__shim_type_info();
 
+    virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const;
     virtual void display() const = 0;
 };
 





More information about the cfe-commits mailing list