Home | History | Annotate | Download | only in test
      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