This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[csl-arm] Revise __cxa_type_match


The attached patch revises __cxa_type_match. The existing implementation was 
based on an outdated version of the EABI.

The additional parameter is necessary to get some bit of c++ EH semantics 
correct. After talking to people who understand g++ better than me, I believe 
the new code is no more broken than the old version of the ABI, or g++ on 
other targets. Fixing it would require more information that is currently 
available in the g++ unwind tables. I'd file a PR, but I can't find the email 
with the example.

Tested with cross to arm-none-eabi.
Applied to csl-arm-branch.

Paul

2004-11-16  Paul Brook  <paul@codesourcery.com>

 * libsupc++/eh_arm.cc: Include cxxabi.h.
 (__cxa_type_match): Update prototype.  Change return values.
 * libsupc++/eh_call.cc (__cxa_call_unexpected): Pass extra argument
 to __cxa_type_match.
 * libsupc++/eh_personality.cc (get_adjusted_ptr): Ditto.
 * libsupc++/unwind-cxx.h (__cxa_type_match_result): Declare.
 (__cxa_type_match): Update prototype.
Index: libsupc++/eh_arm.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/Attic/eh_arm.cc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 eh_arm.cc
--- libsupc++/eh_arm.cc	29 Sep 2004 16:11:56 -0000	1.1.2.2
+++ libsupc++/eh_arm.cc	16 Nov 2004 20:14:44 -0000
@@ -27,6 +27,7 @@
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
+#include <cxxabi.h>
 #include "unwind-cxx.h"
 
 #ifdef __ARM_EABI_UNWINDER__
@@ -39,13 +40,14 @@ using namespace __cxxabiv1;
 // compare against, return whether or not there is a match and if so,
 // update *THROWN_PTR_P.
 
-extern "C" bool
+extern "C" __cxa_type_match_result
 __cxa_type_match(_Unwind_Exception* ue_header,
 		 const std::type_info* catch_type,
+		 bool is_reference __attribute__((unused)),
 		 void** thrown_ptr_p)
 {
   if (!__is_gxx_exception_class(ue_header->exception_class))
-    return false;
+    return ctm_failed;
 
   __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
   const std::type_info* throw_type = xh->exceptionType;
@@ -61,10 +63,24 @@ __cxa_type_match(_Unwind_Exception* ue_h
   if (catch_type->__do_catch(throw_type, &thrown_ptr, 1))
     {
       *thrown_ptr_p = thrown_ptr;
-      return true;
+
+      if (typeid(*catch_type) == typeid (typeid(void*)))
+	{
+	  const __pointer_type_info *catch_pointer_type =
+	    static_cast<const __pointer_type_info *> (catch_type);
+	  const __pointer_type_info *throw_pointer_type =
+	    static_cast<const __pointer_type_info *> (throw_type);
+
+	  if (typeid (*catch_pointer_type->__pointee) != typeid (void)
+	      && (*catch_pointer_type->__pointee != 
+		  *throw_pointer_type->__pointee))
+	    return ctm_succeeded_with_ptr_to_base;
+	}
+
+      return ctm_succeeded;
     }
 
-  return false;
+  return ctm_failed;
 }
 
 extern "C" void
Index: libsupc++/eh_call.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/Attic/eh_call.cc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 eh_call.cc
--- libsupc++/eh_call.cc	22 Sep 2004 15:40:33 -0000	1.1.2.1
+++ libsupc++/eh_call.cc	16 Nov 2004 20:25:23 -0000
@@ -136,7 +136,8 @@ __cxa_call_unexpected(void* exc_obj_in)
 	  offset = _Unwind_decode_target2(offset);
 	  catch_type = (const std::type_info*) (offset);
 
-	  if (__cxa_type_match(&new_xh->unwindHeader, catch_type, &new_ptr))
+	  if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false,
+			       &new_ptr) != ctm_failed)
 	    __throw_exception_again;
 
 	  if (catch_type->__do_catch(&bad_exc, 0, 1))
Index: libsupc++/eh_personality.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/eh_personality.cc,v
retrieving revision 1.13.8.2
diff -u -p -r1.13.8.2 eh_personality.cc
--- libsupc++/eh_personality.cc	22 Sep 2004 15:40:33 -0000	1.13.8.2
+++ libsupc++/eh_personality.cc	16 Nov 2004 20:25:54 -0000
@@ -103,7 +103,8 @@ get_ttype_entry(lsda_header_info* info, 
 /* The ABI provides a routine for matching exception object types.  */
 typedef _Unwind_Control_Block _throw_typet;
 #define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
-  __cxa_type_match (throw_type, catch_type, thrown_ptr_p)
+  (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
+   != ctm_failed)
 
 // Return true if THROW_TYPE matches one if the filter types.
 
Index: libsupc++/unwind-cxx.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/unwind-cxx.h,v
retrieving revision 1.6.8.2
diff -u -p -r1.6.8.2 unwind-cxx.h
--- libsupc++/unwind-cxx.h	22 Sep 2004 15:40:33 -0000	1.6.8.2
+++ libsupc++/unwind-cxx.h	16 Nov 2004 17:16:22 -0000
@@ -124,9 +124,14 @@ extern "C" void __cxa_call_unexpected (v
 extern "C" void __cxa_call_terminate (void*) __attribute__((noreturn));
 
 #ifdef __ARM_EABI_UNWINDER__
-/* Arm EABI specified routines.  */
-extern "C" bool __cxa_type_match (_Unwind_Exception*, const std::type_info*,
-				  void**);
+// Arm EABI specified routines.
+typedef enum {
+  ctm_failed = 0,
+  ctm_succeeded = 1,
+  ctm_succeeded_with_ptr_to_base = 2
+} __cxa_type_match_result;
+extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*,
+				 bool, void**);
 extern "C" void __cxa_begin_cleanup (_Unwind_Exception*);
 extern "C" void __cxa_end_cleanup (_Unwind_Exception*);
 #endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]