llvm-project
172 строки · 2.5 Кб
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{
17void foo() {}
18void 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{
40try
41{
42throw &A::foo;
43assert(false);
44}
45catch (mf2)
46{
47assert(false);
48}
49catch (mf1)
50{
51}
52}
53
54void test2()
55{
56try
57{
58throw &A::bar;
59assert(false);
60}
61catch (mf1)
62{
63assert(false);
64}
65catch (mf2)
66{
67}
68}
69
70
71
72void test_derived()
73{
74try
75{
76throw (mf1)0;
77assert(false);
78}
79catch (dmf2)
80{
81assert(false);
82}
83catch (dmf1)
84{
85assert(false);
86}
87catch (mf1)
88{
89}
90
91try
92{
93throw (mf2)0;
94assert(false);
95}
96catch (dmf1)
97{
98assert(false);
99}
100catch (dmf2)
101{
102assert(false);
103}
104catch (mf2)
105{
106}
107
108assert(!can_convert<mf1>((dmf1)0));
109assert(!can_convert<mf2>((dmf1)0));
110try
111{
112throw (dmf1)0;
113assert(false);
114}
115catch (mf2)
116{
117assert(false);
118}
119catch (mf1)
120{
121assert(false);
122}
123catch (...)
124{
125}
126
127assert(!can_convert<mf1>((dmf2)0));
128assert(!can_convert<mf2>((dmf2)0));
129try
130{
131throw (dmf2)0;
132assert(false);
133}
134catch (mf2)
135{
136assert(false);
137}
138catch (mf1)
139{
140assert(false);
141}
142catch (...)
143{
144}
145}
146
147void test_void()
148{
149assert(!can_convert<void*>(&A::foo));
150try
151{
152throw &A::foo;
153assert(false);
154}
155catch (void*)
156{
157assert(false);
158}
159catch(...)
160{
161}
162}
163
164int main(int, char**)
165{
166test1();
167test2();
168test_derived();
169test_void();
170
171return 0;
172}
173