Home | History | Annotate | Download | only in test
      1 //===--------------------- inherited_exception.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 // This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
     11 //
     12 //  C++ ABI 15.3:
     13 //  A handler is a match for an exception object of type E if
     14 //  /  *  The handler is of type cv T or cv T& and E and T are the same type   \
     15 //  |     (ignoring the top-level cv-qualifiers), or                           |
     16 //  |  *  the handler is of type cv T or cv T& and T is an unambiguous base    |
     17 //  \     class of E, or                                                       /
     18 //     *  the handler is of type cv1 T* cv2 and E is a pointer type that can
     19 //        be converted to the type of the handler by either or both of
     20 //          o  a standard pointer conversion (4.10 [conv.ptr]) not involving
     21 //             conversions to private or protected or ambiguous classes
     22 //          o  a qualification conversion
     23 //     *  the handler is a pointer or pointer to member type and E is
     24 //        std::nullptr_t
     25 //
     26 //===----------------------------------------------------------------------===//
     27 
     28 #include <assert.h>
     29 
     30 struct Base {
     31   int b1;
     32 };
     33 
     34 struct Base2 {
     35   int b2;
     36 };
     37 
     38 struct Child : public Base, public Base2 {
     39   int c;
     40 };
     41 
     42 void f1() {
     43   Child child;
     44   child.b1 = 10;
     45   child.b2 = 11;
     46   child.c = 12;
     47   throw child;
     48 }
     49 
     50 void f2() {
     51   Child child;
     52   child.b1 = 10;
     53   child.b2 = 11;
     54   child.c = 12;
     55   throw static_cast<Base2&>(child);
     56 }
     57 
     58 void f3() {
     59   static Child child;
     60   child.b1 = 10;
     61   child.b2 = 11;
     62   child.c = 12;
     63   throw static_cast<Base2*>(&child);
     64 }
     65 
     66 int main()
     67 {
     68     try
     69     {
     70         f1();
     71         assert(false);
     72     }
     73     catch (const Child& c)
     74     {
     75         assert(true);
     76     }
     77     catch (const Base& b)
     78     {
     79         assert(false);
     80     }
     81     catch (...)
     82     {
     83         assert(false);
     84     }
     85 
     86     try
     87     {
     88         f1();
     89         assert(false);
     90     }
     91     catch (const Base& c)
     92     {
     93         assert(true);
     94     }
     95     catch (const Child& b)
     96     {
     97         assert(false);
     98     }
     99     catch (...)
    100     {
    101         assert(false);
    102     }
    103 
    104     try
    105     {
    106         f1();
    107         assert(false);
    108     }
    109     catch (const Base2& c)
    110     {
    111         assert(true);
    112     }
    113     catch (const Child& b)
    114     {
    115         assert(false);
    116     }
    117     catch (...)
    118     {
    119         assert(false);
    120     }
    121 
    122     try
    123     {
    124         f2();
    125         assert(false);
    126     }
    127     catch (const Child& c)
    128     {
    129         assert(false);
    130     }
    131     catch (const Base& b)
    132     {
    133         assert(false);
    134     }
    135     catch (const Base2& b)
    136     {
    137         assert(true);
    138     }
    139     catch (...)
    140     {
    141         assert(false);
    142     }
    143 
    144     try
    145     {
    146         f3();
    147         assert(false);
    148     }
    149     catch (const Base* c)
    150     {
    151         assert(false);
    152     }
    153     catch (const Child* b)
    154     {
    155         assert(false);
    156     }
    157     catch (const Base2* c)
    158     {
    159         assert(true);
    160     }
    161     catch (...)
    162     {
    163         assert(false);
    164     }
    165 }
    166