blob: b7bdcb64ad74d811c0d89de7440db2017d52d8bf [file] [log] [blame]
Howard Hinnant2d6810f2012-02-01 20:53:21 +00001//===--------------- 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
Eric Fiselier3f7c2072016-01-20 04:06:46 +000010// GCC incorrectly allows PMF type "void (T::*)()" to be caught as "void (T::*)() const"
11// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69375
12// XFAIL: gcc
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000013// UNSUPPORTED: libcxxabi-no-exceptions
Howard Hinnant2d6810f2012-02-01 20:53:21 +000014#include <cassert>
15
16struct A
17{
18 void foo() {}
19 void bar() const {}
20};
21
22typedef void (A::*mf1)();
23typedef void (A::*mf2)() const;
24
Eric Fiselierb6030b92015-04-06 23:03:01 +000025struct B : public A
26{
27};
28
29typedef void (B::*dmf1)();
30typedef void (B::*dmf2)() const;
31
32template <class Tp>
33bool can_convert(Tp) { return true; }
34
35template <class>
36bool can_convert(...) { return false; }
37
38
Howard Hinnant2d6810f2012-02-01 20:53:21 +000039void test1()
40{
41 try
42 {
43 throw &A::foo;
44 assert(false);
45 }
46 catch (mf2)
47 {
48 assert(false);
49 }
50 catch (mf1)
51 {
52 }
53}
54
55void test2()
56{
57 try
58 {
59 throw &A::bar;
60 assert(false);
61 }
62 catch (mf1)
63 {
64 assert(false);
65 }
66 catch (mf2)
67 {
68 }
69}
70
Eric Fiselierb6030b92015-04-06 23:03:01 +000071
72
73void test_derived()
74{
75 try
76 {
77 throw (mf1)0;
78 assert(false);
79 }
80 catch (dmf2)
81 {
82 assert(false);
83 }
84 catch (dmf1)
85 {
86 assert(false);
87 }
88 catch (mf1)
89 {
90 }
91
92 try
93 {
94 throw (mf2)0;
95 assert(false);
96 }
97 catch (dmf1)
98 {
99 assert(false);
100 }
101 catch (dmf2)
102 {
103 assert(false);
104 }
105 catch (mf2)
106 {
107 }
108
109 assert(!can_convert<mf1>((dmf1)0));
110 assert(!can_convert<mf2>((dmf1)0));
111 try
112 {
113 throw (dmf1)0;
114 assert(false);
115 }
116 catch (mf2)
117 {
118 assert(false);
119 }
120 catch (mf1)
121 {
122 assert(false);
123 }
124 catch (...)
125 {
126 }
127
128 assert(!can_convert<mf1>((dmf2)0));
129 assert(!can_convert<mf2>((dmf2)0));
130 try
131 {
132 throw (dmf2)0;
133 assert(false);
134 }
135 catch (mf2)
136 {
137 assert(false);
138 }
139 catch (mf1)
140 {
141 assert(false);
142 }
143 catch (...)
144 {
145 }
146}
147
148void test_void()
149{
150 assert(!can_convert<void*>(&A::foo));
151 try
152 {
153 throw &A::foo;
154 assert(false);
155 }
156 catch (void*)
157 {
158 assert(false);
159 }
160 catch(...)
161 {
162 }
163}
164
Howard Hinnant2d6810f2012-02-01 20:53:21 +0000165int main()
166{
167 test1();
168 test2();
Eric Fiselierb6030b92015-04-06 23:03:01 +0000169 test_derived();
170 test_void();
Howard Hinnant2d6810f2012-02-01 20:53:21 +0000171}