Home | History | Annotate | Download | only in test
      1 //===---------------------- catch_class_04.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 /*
     11     This test checks that adjustedPtr is correct as there exist offsets in this
     12     object for the various subobjects, all of which have a unique id_ to
     13     check against.  It also checks that virtual bases work properly
     14 */
     15 
     16 // UNSUPPORTED: libcxxabi-no-exceptions
     17 
     18 #include <exception>
     19 #include <stdlib.h>
     20 #include <assert.h>
     21 
     22 // Clang emits  warnings about exceptions of type 'Child' being caught by
     23 // an earlier handler of type 'Base'. Congrats clang, you've just
     24 // diagnosed the behavior under test.
     25 #if defined(__clang__)
     26 #pragma clang diagnostic ignored "-Wexceptions"
     27 #endif
     28 
     29 struct B
     30 {
     31     static int count;
     32     int id_;
     33     explicit B(int id) : id_(id) {count++;}
     34     B(const B& a) : id_(a.id_) {count++;}
     35     ~B() {count--;}
     36 };
     37 
     38 int B::count = 0;
     39 
     40 struct C1
     41     : virtual B
     42 {
     43     static int count;
     44     int id_;
     45     explicit C1(int id) : B(id-2), id_(id) {count++;}
     46     C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
     47     ~C1() {count--;}
     48 };
     49 
     50 int C1::count = 0;
     51 
     52 struct C2
     53     : virtual private B
     54 {
     55     static int count;
     56     int id_;
     57     explicit C2(int id) : B(id-2), id_(id) {count++;}
     58     C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
     59     ~C2() {count--;}
     60 };
     61 
     62 int C2::count = 0;
     63 
     64 struct A
     65     : C1, C2
     66 {
     67     static int count;
     68     int id_;
     69     explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;}
     70     A(const A& a) :  B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
     71     ~A() {count--;}
     72 };
     73 
     74 int A::count = 0;
     75 
     76 void f1()
     77 {
     78     assert(A::count == 0);
     79     assert(C1::count == 0);
     80     assert(C2::count == 0);
     81     assert(B::count == 0);
     82     A a(5);
     83     assert(A::count == 1);
     84     assert(C1::count == 1);
     85     assert(C2::count == 1);
     86     assert(B::count == 1);
     87 
     88     assert(a.id_ == 5);
     89     assert(static_cast<C1&>(a).id_ == 4);
     90     assert(static_cast<C2&>(a).id_ == 3);
     91     assert(static_cast<B&>(a).id_ == 8);
     92     throw a;
     93     assert(false);
     94 }
     95 
     96 void f2()
     97 {
     98     try
     99     {
    100         assert(A::count == 0);
    101         assert(C1::count == 0);
    102         assert(C2::count == 0);
    103         assert(B::count == 0);
    104         f1();
    105         assert(false);
    106     }
    107     catch (const A& a)  // can catch A
    108     {
    109         assert(a.id_ == 5);
    110         assert(static_cast<const C1&>(a).id_ == 4);
    111         assert(static_cast<const C2&>(a).id_ == 3);
    112         assert(static_cast<const B&>(a).id_ == 8);
    113         throw;
    114     }
    115     catch (const C1&)
    116     {
    117         assert(false);
    118     }
    119     catch (const C2&)
    120     {
    121         assert(false);
    122     }
    123     catch (const B&)
    124     {
    125         assert(false);
    126     }
    127 }
    128 
    129 void f3()
    130 {
    131     try
    132     {
    133         assert(A::count == 0);
    134         assert(C1::count == 0);
    135         assert(C2::count == 0);
    136         assert(B::count == 0);
    137         f2();
    138         assert(false);
    139     }
    140     catch (const B& a)  // can catch B
    141     {
    142         assert(static_cast<const B&>(a).id_ == 8);
    143         throw;
    144     }
    145     catch (const C1& c1)
    146     {
    147         assert(false);
    148     }
    149     catch (const C2&)
    150     {
    151         assert(false);
    152     }
    153 }
    154 
    155 void f4()
    156 {
    157     try
    158     {
    159         assert(A::count == 0);
    160         assert(C1::count == 0);
    161         assert(C2::count == 0);
    162         assert(B::count == 0);
    163         f3();
    164         assert(false);
    165     }
    166     catch (const C2& c2)  // can catch C2
    167     {
    168         assert(c2.id_ == 3);
    169         throw;
    170     }
    171     catch (const B& a)  // can not catch B (ambiguous base)
    172     {
    173         assert(false);
    174     }
    175     catch (const C1&)
    176     {
    177         assert(false);
    178     }
    179 }
    180 
    181 void f5()
    182 {
    183     try
    184     {
    185         assert(A::count == 0);
    186         assert(C1::count == 0);
    187         assert(C2::count == 0);
    188         assert(B::count == 0);
    189         f4();
    190         assert(false);
    191     }
    192     catch (const C1& c1)  // can catch C1
    193     {
    194         assert(c1.id_ == 4);
    195         assert(static_cast<const B&>(c1).id_ == 8);
    196         throw;
    197     }
    198     catch (const B& a)
    199     {
    200         assert(false);
    201     }
    202     catch (const C2&)
    203     {
    204         assert(false);
    205     }
    206 }
    207 
    208 int main()
    209 {
    210     try
    211     {
    212         f5();
    213         assert(false);
    214     }
    215     catch (...)
    216     {
    217     }
    218     assert(A::count == 0);
    219     assert(C1::count == 0);
    220     assert(C2::count == 0);
    221     assert(B::count == 0);
    222 }
    223