xref: /llvm-project/libcxxabi/test/catch_member_function_pointer_01.pass.cpp (revision eb8650a75793b2bd079d0c8901ff066f129061da)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // GCC incorrectly allows PMF type "void (T::*)()" to be caught as "void (T::*)() const"
10 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69375
11 // XFAIL: gcc
12 // UNSUPPORTED: no-exceptions
13 #include <cassert>
14 
15 struct A
16 {
fooA17     void foo() {}
barA18     void bar() const {}
19 };
20 
21 typedef void (A::*mf1)();
22 typedef void (A::*mf2)() const;
23 
24 struct B : public A
25 {
26 };
27 
28 typedef void (B::*dmf1)();
29 typedef void (B::*dmf2)() const;
30 
31 template <class Tp>
can_convert(Tp)32 bool can_convert(Tp) { return true; }
33 
34 template <class>
can_convert(...)35 bool can_convert(...) { return false; }
36 
37 
test1()38 void test1()
39 {
40     try
41     {
42         throw &A::foo;
43         assert(false);
44     }
45     catch (mf2)
46     {
47         assert(false);
48     }
49     catch (mf1)
50     {
51     }
52 }
53 
test2()54 void test2()
55 {
56     try
57     {
58         throw &A::bar;
59         assert(false);
60     }
61     catch (mf1)
62     {
63         assert(false);
64     }
65     catch (mf2)
66     {
67     }
68 }
69 
70 
71 
test_derived()72 void test_derived()
73 {
74     try
75     {
76         throw (mf1)0;
77         assert(false);
78     }
79     catch (dmf2)
80     {
81        assert(false);
82     }
83     catch (dmf1)
84     {
85        assert(false);
86     }
87     catch (mf1)
88     {
89     }
90 
91     try
92     {
93         throw (mf2)0;
94         assert(false);
95     }
96     catch (dmf1)
97     {
98        assert(false);
99     }
100     catch (dmf2)
101     {
102        assert(false);
103     }
104     catch (mf2)
105     {
106     }
107 
108     assert(!can_convert<mf1>((dmf1)0));
109     assert(!can_convert<mf2>((dmf1)0));
110     try
111     {
112         throw (dmf1)0;
113         assert(false);
114     }
115     catch (mf2)
116     {
117        assert(false);
118     }
119     catch (mf1)
120     {
121        assert(false);
122     }
123     catch (...)
124     {
125     }
126 
127     assert(!can_convert<mf1>((dmf2)0));
128     assert(!can_convert<mf2>((dmf2)0));
129     try
130     {
131         throw (dmf2)0;
132         assert(false);
133     }
134     catch (mf2)
135     {
136        assert(false);
137     }
138     catch (mf1)
139     {
140         assert(false);
141     }
142     catch (...)
143     {
144     }
145 }
146 
test_void()147 void test_void()
148 {
149     assert(!can_convert<void*>(&A::foo));
150     try
151     {
152         throw &A::foo;
153         assert(false);
154     }
155     catch (void*)
156     {
157         assert(false);
158     }
159     catch(...)
160     {
161     }
162 }
163 
main(int,char **)164 int main(int, char**)
165 {
166     test1();
167     test2();
168     test_derived();
169     test_void();
170 
171     return 0;
172 }
173