/ test / catch_member_function_pointer_01.pass.cpp
catch_member_function_pointer_01.pass.cpp
  1  //===--------------- catch_member_function_pointer_01.cpp -----------------===//
  2  //
  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
  6  //
  7  //===----------------------------------------------------------------------===//
  8  
  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
 12  // UNSUPPORTED: no-exceptions
 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  
 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  
 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  
 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  
164  int main(int, char**)
165  {
166      test1();
167      test2();
168      test_derived();
169      test_void();
170  
171      return 0;
172  }