[libcxxabi] r288457 - Update implementation of ABI support for throwing noexcept function pointers

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 1 18:06:54 PST 2016


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']




More information about the cfe-commits mailing list