1 //===--------------- catch_member_function_pointer_01.cpp -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <cassert>
11 
12 struct A
13 {
14     void foo() {}
15     void bar() const {}
16 };
17 
18 typedef void (A::*mf1)();
19 typedef void (A::*mf2)() const;
20 
21 struct B : public A
22 {
23 };
24 
25 typedef void (B::*dmf1)();
26 typedef void (B::*dmf2)() const;
27 
28 template <class Tp>
29 bool can_convert(Tp) { return true; }
30 
31 template <class>
32 bool can_convert(...) { return false; }
33 
34 
35 void test1()
36 {
37     try
38     {
39         throw &A::foo;
40         assert(false);
41     }
42     catch (mf2)
43     {
44         assert(false);
45     }
46     catch (mf1)
47     {
48     }
49 }
50 
51 void test2()
52 {
53     try
54     {
55         throw &A::bar;
56         assert(false);
57     }
58     catch (mf1)
59     {
60         assert(false);
61     }
62     catch (mf2)
63     {
64     }
65 }
66 
67 
68 
69 void test_derived()
70 {
71     try
72     {
73         throw (mf1)0;
74         assert(false);
75     }
76     catch (dmf2)
77     {
78        assert(false);
79     }
80     catch (dmf1)
81     {
82        assert(false);
83     }
84     catch (mf1)
85     {
86     }
87 
88     try
89     {
90         throw (mf2)0;
91         assert(false);
92     }
93     catch (dmf1)
94     {
95        assert(false);
96     }
97     catch (dmf2)
98     {
99        assert(false);
100     }
101     catch (mf2)
102     {
103     }
104 
105     assert(!can_convert<mf1>((dmf1)0));
106     assert(!can_convert<mf2>((dmf1)0));
107     try
108     {
109         throw (dmf1)0;
110         assert(false);
111     }
112     catch (mf2)
113     {
114        assert(false);
115     }
116     catch (mf1)
117     {
118        assert(false);
119     }
120     catch (...)
121     {
122     }
123 
124     assert(!can_convert<mf1>((dmf2)0));
125     assert(!can_convert<mf2>((dmf2)0));
126     try
127     {
128         throw (dmf2)0;
129         assert(false);
130     }
131     catch (mf2)
132     {
133        assert(false);
134     }
135     catch (mf1)
136     {
137         assert(false);
138     }
139     catch (...)
140     {
141     }
142 }
143 
144 void test_void()
145 {
146     assert(!can_convert<void*>(&A::foo));
147     try
148     {
149         throw &A::foo;
150         assert(false);
151     }
152     catch (void*)
153     {
154         assert(false);
155     }
156     catch(...)
157     {
158     }
159 }
160 
161 int main()
162 {
163     test1();
164     test2();
165     test_derived();
166     test_void();
167 }
168