Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 1 | //===--------------- catch_member_function_pointer_01.cpp -----------------===// |
2 | // | ||||
Chandler Carruth | 57b08b0 | 2019-01-19 10:56:40 +0000 | [diff] [blame] | 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 | ||||
Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 6 | // |
7 | //===----------------------------------------------------------------------===// | ||||
8 | |||||
Eric Fiselier | 3f7c207 | 2016-01-20 04:06:46 +0000 | [diff] [blame] | 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 | ||||
Louis Dionne | 8c61114 | 2020-04-17 10:29:15 -0400 | [diff] [blame] | 12 | // UNSUPPORTED: no-exceptions |
Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 13 | #include <cassert> |
14 | |||||
15 | struct A | ||||
16 | { | ||||
17 | void foo() {} | ||||
18 | void bar() const {} | ||||
19 | }; | ||||
20 | |||||
21 | typedef void (A::*mf1)(); | ||||
22 | typedef void (A::*mf2)() const; | ||||
23 | |||||
Eric Fiselier | b6030b9 | 2015-04-06 23:03:01 +0000 | [diff] [blame] | 24 | struct B : public A |
25 | { | ||||
26 | }; | ||||
27 | |||||
28 | typedef void (B::*dmf1)(); | ||||
29 | typedef void (B::*dmf2)() const; | ||||
30 | |||||
31 | template <class Tp> | ||||
32 | bool can_convert(Tp) { return true; } | ||||
33 | |||||
34 | template <class> | ||||
35 | bool can_convert(...) { return false; } | ||||
36 | |||||
37 | |||||
Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 38 | void 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 | |||||
54 | void 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 | |||||
Eric Fiselier | b6030b9 | 2015-04-06 23:03:01 +0000 | [diff] [blame] | 70 | |
71 | |||||
72 | void 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 | |||||
147 | void 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 | |||||
Louis Dionne | 504bc07 | 2020-10-08 13:36:33 -0400 | [diff] [blame] | 164 | int main(int, char**) |
Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 165 | { |
166 | test1(); | ||||
167 | test2(); | ||||
Eric Fiselier | b6030b9 | 2015-04-06 23:03:01 +0000 | [diff] [blame] | 168 | test_derived(); |
169 | test_void(); | ||||
Louis Dionne | 504bc07 | 2020-10-08 13:36:33 -0400 | [diff] [blame] | 170 | |
171 | return 0; | ||||
Howard Hinnant | 2d6810f | 2012-02-01 20:53:21 +0000 | [diff] [blame] | 172 | } |