• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  // 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
13  // UNSUPPORTED: libcxxabi-no-exceptions
14  #include <cassert>
15  
16  struct A
17  {
fooA18      void foo() {}
barA19      void bar() const {}
20  };
21  
22  typedef void (A::*mf1)();
23  typedef void (A::*mf2)() const;
24  
25  struct B : public A
26  {
27  };
28  
29  typedef void (B::*dmf1)();
30  typedef void (B::*dmf2)() const;
31  
32  template <class Tp>
can_convert(Tp)33  bool can_convert(Tp) { return true; }
34  
35  template <class>
can_convert(...)36  bool can_convert(...) { return false; }
37  
38  
test1()39  void 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  
test2()55  void 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  
71  
72  
test_derived()73  void 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  
test_void()148  void 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  
main()165  int main()
166  {
167      test1();
168      test2();
169      test_derived();
170      test_void();
171  }
172