1 //===----------------------------------------------------------------------===// 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 { fooA17 void foo() {} barA18 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> can_convert(Tp)32bool can_convert(Tp) { return true; } 33 34 template <class> can_convert(...)35bool can_convert(...) { return false; } 36 37 test1()38void 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 test2()54void 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 test_derived()72void 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 test_void()147void 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 main(int,char **)164int main(int, char**) 165 { 166 test1(); 167 test2(); 168 test_derived(); 169 test_void(); 170 171 return 0; 172 } 173