diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-02 05:06:53 +0300 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-02 05:06:53 +0300 |
commit | 6afcab35887245f36751790ba33debaf74b0d2ee (patch) | |
tree | 4ffdf6a346334f87c7a209d04949844b695e71b9 /libcxxabi/src/private_typeinfo.cpp | |
parent | 13bba6966f9f4905bfc2a1fc7863edcfa0f3fbe2 (diff) |
Update implementation of ABI support for throwing noexcept function pointers
and catching as non-noexcept to match the final design per discusson on
cxx-abi-dev.
llvm-svn: 288457
Diffstat (limited to 'libcxxabi/src/private_typeinfo.cpp')
-rw-r--r-- | libcxxabi/src/private_typeinfo.cpp | 57 |
1 files changed, 8 insertions, 49 deletions
diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp index 6112a1f92a94..e7995ed9fbfa 100644 --- a/libcxxabi/src/private_typeinfo.cpp +++ b/libcxxabi/src/private_typeinfo.cpp @@ -105,45 +105,6 @@ __function_type_info::~__function_type_info() { } -// __qualified_function_type_info - -__qualified_function_type_info::~__qualified_function_type_info() -{ -} - -// Determine if a function pointer conversion can convert a pointer (or pointer -// to member) to type x into a pointer (or pointer to member) to type y. -static bool is_function_pointer_conversion(const std::type_info* x, - const std::type_info* y) -{ - const unsigned int discardable_quals = - __qualified_function_type_info::__noexcept_mask | - __qualified_function_type_info::__transaction_safe_mask | - __qualified_function_type_info::__noreturn_mask; - - // If x has only discardable qualifiers and y is unqualified, then - // conversion is permitted. - const __qualified_function_type_info* qual_x = - dynamic_cast<const __qualified_function_type_info *>(x); - if (!qual_x) - return false; - if ((qual_x->__qualifiers & ~discardable_quals) == 0 && - is_equal(qual_x->__base_type, y, false)) - return true; - - // Otherwise, x's qualifiers must be the same as y's, plus some discardable - // ones. - const __qualified_function_type_info* qual_y = - dynamic_cast<const __qualified_function_type_info *>(y); - if (!qual_y) - return false; - if (qual_y->__qualifiers & ~qual_x->__qualifiers) - return false; - if (qual_x->__qualifiers & ~qual_y->__qualifiers & ~discardable_quals) - return false; - return is_equal(qual_x->__base_type, qual_y->__base_type, false); -} - // __enum_type_info __enum_type_info::~__enum_type_info() @@ -429,15 +390,13 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type, // Do the dereference adjustment if (adjustedPtr != NULL) adjustedPtr = *static_cast<void**>(adjustedPtr); - // bullet 3B - if (thrown_pointer_type->__flags & ~__flags) + // bullet 3B and 3C + if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) + return false; + if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) return false; if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) return true; - // bullet 3C - if (is_function_pointer_conversion(thrown_pointer_type->__pointee, - __pointee)) - return true; // bullet 3A if (is_equal(__pointee, &typeid(void), false)) { // pointers to functions cannot be converted to void*. @@ -543,11 +502,11 @@ bool __pointer_to_member_type_info::can_catch( dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); if (thrown_pointer_type == 0) return false; - if (thrown_pointer_type->__flags & ~__flags) + if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) + return false; + if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) return false; - if (!is_equal(__pointee, thrown_pointer_type->__pointee, false) && - !is_function_pointer_conversion(thrown_pointer_type->__pointee, - __pointee)) + if (!is_equal(__pointee, thrown_pointer_type->__pointee, false)) return false; if (is_equal(__context, thrown_pointer_type->__context, false)) return true; |