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
15struct A
16{
17 void foo() {}
18 void bar() const {}
19};
20
21typedef void (A::*mf1)();
22typedef void (A::*mf2)() const;
23
24struct B : public A
25{
26};
27
28typedef void (B::*dmf1)();
29typedef void (B::*dmf2)() const;
30
31template <class Tp>
32bool can_convert(Tp) { return true; }
33
34template <class>
35bool can_convert(...) { return false; }
36
37
38void 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
54void 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
72void 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
147void 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
164int main(int, char**)
165{
166 test1();
167 test2();
168 test_derived();
169 test_void();
170
171 return 0;
172}
173

source code of libcxxabi/test/catch_member_function_pointer_01.pass.cpp