Home | History | Annotate | Download | only in tests
      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 #include <exception>
     17 #include <stdlib.h>
     18 #include <assert.h>
     19 
     20 struct B
     21 {
     22     static int count;
     23     int id_;
     24     explicit B(int id) : id_(id) {count++;}
     25     B(const B& a) : id_(a.id_) {count++;}
     26     ~B() {count--;}
     27 };
     28 
     29 int B::count = 0;
     30 
     31 struct C1
     32     : virtual B
     33 {
     34     static int count;
     35     int id_;
     36     explicit C1(int id) : B(id-2), id_(id) {count++;}
     37     C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
     38     ~C1() {count--;}
     39 };
     40 
     41 int C1::count = 0;
     42 
     43 struct C2
     44     : virtual private B
     45 {
     46     static int count;
     47     int id_;
     48     explicit C2(int id) : B(id-2), id_(id) {count++;}
     49     C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
     50     ~C2() {count--;}
     51 };
     52 
     53 int C2::count = 0;
     54 
     55 struct A
     56     : C1, C2
     57 {
     58     static int count;
     59     int id_;
     60     explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;}
     61     A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;}
     62     ~A() {count--;}
     63 };
     64 
     65 int A::count = 0;
     66 
     67 void f1()
     68 {
     69     assert(A::count == 0);
     70     assert(C1::count == 0);
     71     assert(C2::count == 0);
     72     assert(B::count == 0);
     73     A a(5);
     74     assert(A::count == 1);
     75     assert(C1::count == 1);
     76     assert(C2::count == 1);
     77     assert(B::count == 1);
     78 
     79     assert(a.id_ == 5);
     80     assert(static_cast<C1&>(a).id_ == 4);
     81     assert(static_cast<C2&>(a).id_ == 3);
     82     assert(static_cast<B&>(a).id_ == 8);
     83     throw a;
     84     assert(false);
     85 }
     86 
     87 void f2()
     88 {
     89     try
     90     {
     91         assert(A::count == 0);
     92         assert(C1::count == 0);
     93         assert(C2::count == 0);
     94         assert(B::count == 0);
     95         f1();
     96         assert(false);
     97     }
     98     catch (const A& a)  // can catch A
     99     {
    100         assert(a.id_ == 5);
    101         assert(static_cast<const C1&>(a).id_ == 4);
    102         assert(static_cast<const C2&>(a).id_ == 3);
    103         assert(static_cast<const B&>(a).id_ == 8);
    104         throw;
    105     }
    106     catch (const C1&)
    107     {
    108         assert(false);
    109     }
    110     catch (const C2&)
    111     {
    112         assert(false);
    113     }
    114     catch (const B&)
    115     {
    116         assert(false);
    117     }
    118 }
    119 
    120 void f3()
    121 {
    122     try
    123     {
    124         assert(A::count == 0);
    125         assert(C1::count == 0);
    126         assert(C2::count == 0);
    127         assert(B::count == 0);
    128         f2();
    129         assert(false);
    130     }
    131     catch (const B& a)  // can catch B
    132     {
    133         assert(static_cast<const B&>(a).id_ == 8);
    134         throw;
    135     }
    136     catch (const C1& c1)
    137     {
    138         assert(false);
    139     }
    140     catch (const C2&)
    141     {
    142         assert(false);
    143     }
    144 }
    145 
    146 void f4()
    147 {
    148     try
    149     {
    150         assert(A::count == 0);
    151         assert(C1::count == 0);
    152         assert(C2::count == 0);
    153         assert(B::count == 0);
    154         f3();
    155         assert(false);
    156     }
    157     catch (const C2& c2)  // can catch C2
    158     {
    159         assert(c2.id_ == 3);
    160         throw;
    161     }
    162     catch (const B& a)  // can not catch B (ambiguous base)
    163     {
    164         assert(false);
    165     }
    166     catch (const C1&)
    167     {
    168         assert(false);
    169     }
    170 }
    171 
    172 void f5()
    173 {
    174     try
    175     {
    176         assert(A::count == 0);
    177         assert(C1::count == 0);
    178         assert(C2::count == 0);
    179         assert(B::count == 0);
    180         f4();
    181         assert(false);
    182     }
    183     catch (const C1& c1)  // can catch C1
    184     {
    185         assert(c1.id_ == 4);
    186         assert(static_cast<const B&>(c1).id_ == 8);
    187         throw;
    188     }
    189     catch (const B& a)
    190     {
    191         assert(false);
    192     }
    193     catch (const C2&)
    194     {
    195         assert(false);
    196     }
    197 }
    198 
    199 int main()
    200 {
    201     try
    202     {
    203         f5();
    204         assert(false);
    205     }
    206     catch (...)
    207     {
    208     }
    209     assert(A::count == 0);
    210     assert(C1::count == 0);
    211     assert(C2::count == 0);
    212     assert(B::count == 0);
    213 }
    214