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