summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranonymous <local@localhost>2010-11-25 04:16:44 +0000
committeranonymous <local@localhost>2010-11-25 04:16:44 +0000
commit0f29a300da1302eb27b0c5f561834d3a7ce5dfe4 (patch)
tree23afc0726d43d995f48b107d8a040b3a89cc65b7
parente86befa5c02daa2fdc80539794a5208cbd5bbe28 (diff)
downloadlibcxxrt-0f29a300da1302eb27b0c5f561834d3a7ce5dfe4.tar.gz
libcxxrt-0f29a300da1302eb27b0c5f561834d3a7ce5dfe4.tar.bz2
libcxxrt-0f29a300da1302eb27b0c5f561834d3a7ce5dfe4.tar.xz
Fixed throwing / catching pointers.
-rw-r--r--src/exception.cc14
-rw-r--r--test/test_exception.cc17
2 files changed, 30 insertions, 1 deletions
diff --git a/src/exception.cc b/src/exception.cc
index bdf42a8..ecc3732 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -583,6 +583,11 @@ static std::type_info *get_type_info_entry(_Unwind_Context *context,
static bool check_type_signature(__cxa_exception *ex, std::type_info *type)
{
void *exception_ptr = (void*)(ex+1);
+ __pointer_type_info *ptr_type = dynamic_cast<__pointer_type_info*>(ex->exceptionType);
+ if (0 != ptr_type)
+ {
+ exception_ptr = *(void**)exception_ptr;
+ }
// Always match a catchall, even with a foreign exception
//
// Note: A 0 here is a catchall, not a cleanup, so we return true to
@@ -613,6 +618,15 @@ static bool check_type_signature(__cxa_exception *ex, std::type_info *type)
ex->adjustedPtr = cls_type->cast_to(exception_ptr, target_cls_type);
return 0 != ex->adjustedPtr;
}
+ __pointer_type_info *target_ptr_type = dynamic_cast<__pointer_type_info*>(type);
+ if ((0 != ptr_type) && (0 != target_ptr_type) &&
+ (ptr_type->__pointee == target_ptr_type->__pointee) &&
+ ((target_ptr_type->__flags & ~__pbase_type_info::__const_mask) ==
+ ptr_type->__flags))
+ {
+ ex->adjustedPtr = exception_ptr;
+ return true;
+ }
return false;
}
/**
diff --git a/test/test_exception.cc b/test/test_exception.cc
index eb738ba..44fe5d0 100644
--- a/test/test_exception.cc
+++ b/test/test_exception.cc
@@ -5,7 +5,7 @@
#include <exception>
-#define fprintf(...)
+//#define fprintf(...)
void log(void* ignored)
{
@@ -178,6 +178,21 @@ void test_exceptions(void)
catch (int64_t i) {
TEST(0, "Caught int64_t, but that violates an exception spec");
}
+ int a;
+ try {
+ throw &a;
+ }
+ catch (const int *b)
+ {
+ TEST(&a==b, "Caught const int from thrown int");
+ }
+ try {
+ throw &a;
+ }
+ catch (int *b)
+ {
+ TEST(&a==b, "Caught int from thrown int");
+ }
//printf("Test: %s\n",
}