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 { 18 void foo() {} 19 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> 33 bool can_convert(Tp) { return true; } 34 35 template <class> 36 bool can_convert(...) { return false; } 37 38 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 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 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 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 165 int main() 166 { 167 test1(); 168 test2(); 169 test_derived(); 170 test_void(); 171 } 172