173 lines · cpp
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-exception6//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=6937511// XFAIL: gcc12// UNSUPPORTED: no-exceptions13#include <cassert>14 15struct A16{17 void foo() {}18 void bar() const {}19};20 21typedef void (A::*mf1)();22typedef void (A::*mf2)() const;23 24struct B : public A25{26};27 28typedef void (B::*dmf1)();29typedef void (B::*dmf2)() const;30 31template <class Tp>32bool can_convert(Tp) { return true; }33 34template <class>35bool can_convert(...) { return false; }36 37 38void test1()39{40 try41 {42 throw &A::foo;43 assert(false);44 }45 catch (mf2)46 {47 assert(false);48 }49 catch (mf1)50 {51 }52}53 54void test2()55{56 try57 {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 72void test_derived()73{74 try75 {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 try92 {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 try111 {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 try130 {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 147void test_void()148{149 assert(!can_convert<void*>(&A::foo));150 try151 {152 throw &A::foo;153 assert(false);154 }155 catch (void*)156 {157 assert(false);158 }159 catch(...)160 {161 }162}163 164int main(int, char**)165{166 test1();167 test2();168 test_derived();169 test_void();170 171 return 0;172}173