summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-02 02:06:53 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-02 02:06:53 +0000
commitf1636207ad8e142a11f80860ea27ea92fcc8c776 (patch)
treea65fa30199c45e4f6e26a2d029001c9e64b4be9b
parent2ecedcc0a1605ebeaa0afe3ab6fabe5dc8d5a2f8 (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. git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@288457 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--src/private_typeinfo.cpp57
-rw-r--r--src/private_typeinfo.h44
-rw-r--r--test/catch_function_03.pass.cpp4
-rw-r--r--test/catch_member_function_pointer_02.pass.cpp4
-rw-r--r--test/libcxxabi/test/config.py2
5 files changed, 30 insertions, 81 deletions
diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp
index 6112a1f..e7995ed 100644
--- a/src/private_typeinfo.cpp
+++ b/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;
diff --git a/src/private_typeinfo.h b/src/private_typeinfo.h
index fa6bd63..f3d3e1d 100644
--- a/src/private_typeinfo.h
+++ b/src/private_typeinfo.h
@@ -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();
diff --git a/test/catch_function_03.pass.cpp b/test/catch_function_03.pass.cpp
index 4118fde..c0b33fd 100644
--- a/test/catch_function_03.pass.cpp
+++ b/test/catch_function_03.pass.cpp
@@ -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
}
diff --git a/test/catch_member_function_pointer_02.pass.cpp b/test/catch_member_function_pointer_02.pass.cpp
index 860d8ed..266337f 100644
--- a/test/catch_member_function_pointer_02.pass.cpp
+++ b/test/catch_member_function_pointer_02.pass.cpp
@@ -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
}
diff --git a/test/libcxxabi/test/config.py b/test/libcxxabi/test/config.py
index 7cb1e9b..3d5a235 100644
--- a/test/libcxxabi/test/config.py
+++ b/test/libcxxabi/test/config.py
@@ -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']