diff libcxxabi/test/catch_member_function_pointer_01.pass.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcxxabi/test/catch_member_function_pointer_01.pass.cpp	Thu Feb 13 15:10:13 2020 +0900
@@ -0,0 +1,170 @@
+//===--------------- catch_member_function_pointer_01.cpp -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// GCC incorrectly allows PMF type "void (T::*)()" to be caught as "void (T::*)() const"
+// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69375
+// XFAIL: gcc
+// UNSUPPORTED: libcxxabi-no-exceptions
+#include <cassert>
+
+struct A
+{
+    void foo() {}
+    void bar() const {}
+};
+
+typedef void (A::*mf1)();
+typedef void (A::*mf2)() const;
+
+struct B : public A
+{
+};
+
+typedef void (B::*dmf1)();
+typedef void (B::*dmf2)() const;
+
+template <class Tp>
+bool can_convert(Tp) { return true; }
+
+template <class>
+bool can_convert(...) { return false; }
+
+
+void test1()
+{
+    try
+    {
+        throw &A::foo;
+        assert(false);
+    }
+    catch (mf2)
+    {
+        assert(false);
+    }
+    catch (mf1)
+    {
+    }
+}
+
+void test2()
+{
+    try
+    {
+        throw &A::bar;
+        assert(false);
+    }
+    catch (mf1)
+    {
+        assert(false);
+    }
+    catch (mf2)
+    {
+    }
+}
+
+
+
+void test_derived()
+{
+    try
+    {
+        throw (mf1)0;
+        assert(false);
+    }
+    catch (dmf2)
+    {
+       assert(false);
+    }
+    catch (dmf1)
+    {
+       assert(false);
+    }
+    catch (mf1)
+    {
+    }
+
+    try
+    {
+        throw (mf2)0;
+        assert(false);
+    }
+    catch (dmf1)
+    {
+       assert(false);
+    }
+    catch (dmf2)
+    {
+       assert(false);
+    }
+    catch (mf2)
+    {
+    }
+
+    assert(!can_convert<mf1>((dmf1)0));
+    assert(!can_convert<mf2>((dmf1)0));
+    try
+    {
+        throw (dmf1)0;
+        assert(false);
+    }
+    catch (mf2)
+    {
+       assert(false);
+    }
+    catch (mf1)
+    {
+       assert(false);
+    }
+    catch (...)
+    {
+    }
+
+    assert(!can_convert<mf1>((dmf2)0));
+    assert(!can_convert<mf2>((dmf2)0));
+    try
+    {
+        throw (dmf2)0;
+        assert(false);
+    }
+    catch (mf2)
+    {
+       assert(false);
+    }
+    catch (mf1)
+    {
+        assert(false);
+    }
+    catch (...)
+    {
+    }
+}
+
+void test_void()
+{
+    assert(!can_convert<void*>(&A::foo));
+    try
+    {
+        throw &A::foo;
+        assert(false);
+    }
+    catch (void*)
+    {
+        assert(false);
+    }
+    catch(...)
+    {
+    }
+}
+
+int main()
+{
+    test1();
+    test2();
+    test_derived();
+    test_void();
+}