Author: rsmith Date: Thu Dec 1 20:06:53 2016 New Revision: 288457 URL: http://llvm.org/viewvc/llvm-project?rev=288457&view=rev Log: 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.
Modified: libcxxabi/trunk/src/private_typeinfo.cpp libcxxabi/trunk/src/private_typeinfo.h libcxxabi/trunk/test/catch_function_03.pass.cpp libcxxabi/trunk/test/catch_member_function_pointer_02.pass.cpp libcxxabi/trunk/test/libcxxabi/test/config.py Modified: libcxxabi/trunk/src/private_typeinfo.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=288457&r1=288456&r2=288457&view=diff ============================================================================== --- libcxxabi/trunk/src/private_typeinfo.cpp (original) +++ libcxxabi/trunk/src/private_typeinfo.cpp Thu Dec 1 20:06:53 2016 @@ -105,45 +105,6 @@ __function_type_info::~__function_type_i { } -// __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 __s // 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_ 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; Modified: libcxxabi/trunk/src/private_typeinfo.h URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.h?rev=288457&r1=288456&r2=288457&view=diff ============================================================================== --- libcxxabi/trunk/src/private_typeinfo.h (original) +++ libcxxabi/trunk/src/private_typeinfo.h Thu Dec 1 20:06:53 2016 @@ -49,33 +49,6 @@ public: void *&) const; }; -// This implements the following proposal from cxx-abi-dev (not yet part of the -// ABI document): -// -// http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002988.html -// -// This is necessary for support of http://wg21.link/p0012, which permits throwing -// noexcept function and member function pointers and catching them as non-noexcept -// pointers. -class _LIBCXXABI_TYPE_VIS __qualified_function_type_info : public __shim_type_info { -public: - const __function_type_info* __base_type; - unsigned int __qualifiers; - - enum __qualifiers_mask { - __const_mask = 0x01, - __volatile_mask = 0x02, - __restrict_mask = 0x04, - __lval_ref_mask = 0x08, - __rval_ref_mask = 0x10, - __noexcept_mask = 0x20, - __transaction_safe_mask = 0x40, - __noreturn_mask = 0x80 - }; - - _LIBCXXABI_HIDDEN virtual ~__qualified_function_type_info(); -}; - class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info { public: _LIBCXXABI_HIDDEN virtual ~__enum_type_info(); @@ -233,7 +206,22 @@ public: __volatile_mask = 0x2, __restrict_mask = 0x4, __incomplete_mask = 0x8, - __incomplete_class_mask = 0x10 + __incomplete_class_mask = 0x10, + __transaction_safe_mask = 0x20, + // This implements the following proposal from cxx-abi-dev (not yet part of + // the ABI document): + // + // http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002986.html + // + // This is necessary for support of http://wg21.link/p0012, which permits + // throwing noexcept function and member function pointers and catching + // them as non-noexcept pointers. + __noexcept_mask = 0x40, + + // Flags that cannot be removed by a standard conversion. + __no_remove_flags_mask = __const_mask | __volatile_mask | __restrict_mask, + // Flags that cannot be added by a standard conversion. + __no_add_flags_mask = __transaction_safe_mask | __noexcept_mask }; _LIBCXXABI_HIDDEN virtual ~__pbase_type_info(); Modified: libcxxabi/trunk/test/catch_function_03.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/catch_function_03.pass.cpp?rev=288457&r1=288456&r2=288457&view=diff ============================================================================== --- libcxxabi/trunk/test/catch_function_03.pass.cpp (original) +++ libcxxabi/trunk/test/catch_function_03.pass.cpp Thu Dec 1 20:06:53 2016 @@ -9,7 +9,7 @@ // Can a noexcept function pointer be caught by a non-noexcept catch clause? // UNSUPPORTED: c++98, c++03, c++11, c++14 -// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-qualified-function-types +// UNSUPPORTED: libcxxabi-no-exceptions #include <cassert> @@ -57,9 +57,11 @@ void check_deep() { int main() { +#ifdef __cpp_noexcept_function_type check<false, false>(); check<false, true>(); check<true, false>(); check<true, true>(); check_deep(); +#endif } Modified: libcxxabi/trunk/test/catch_member_function_pointer_02.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/catch_member_function_pointer_02.pass.cpp?rev=288457&r1=288456&r2=288457&view=diff ============================================================================== --- libcxxabi/trunk/test/catch_member_function_pointer_02.pass.cpp (original) +++ libcxxabi/trunk/test/catch_member_function_pointer_02.pass.cpp Thu Dec 1 20:06:53 2016 @@ -10,7 +10,7 @@ // Can a noexcept member function pointer be caught by a non-noexcept catch // clause? // UNSUPPORTED: c++98, c++03, c++11, c++14 -// UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-qualified-function-types +// UNSUPPORTED: libcxxabi-no-exceptions #include <cassert> @@ -60,9 +60,11 @@ void check_deep() { int main() { +#ifdef __cpp_noexcept_function_type check<false, false>(); check<false, true>(); check<true, false>(); check<true, true>(); check_deep(); +#endif } Modified: libcxxabi/trunk/test/libcxxabi/test/config.py URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/libcxxabi/test/config.py?rev=288457&r1=288456&r2=288457&view=diff ============================================================================== --- libcxxabi/trunk/test/libcxxabi/test/config.py (original) +++ libcxxabi/trunk/test/libcxxabi/test/config.py Thu Dec 1 20:06:53 2016 @@ -37,8 +37,6 @@ class Configuration(LibcxxConfiguration) super(Configuration, self).configure_features() if not self.get_lit_bool('enable_exceptions', True): self.config.available_features.add('libcxxabi-no-exceptions') - if not self.cxx.addCompileFlagIfSupported(['-Xclang', '-mqualified-function-type-info']): - self.config.available_features.add("libcxxabi-no-qualified-function-types") def configure_compile_flags(self): self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER'] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits