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 #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 A a(5);
     68 
     69 void f1()
     70 {
     71     throw &a;
     72     assert(false);
     73 }
     74 
     75 void f2()
     76 {
     77     try
     78     {
     79         f1();
     80         assert(false);
     81     }
     82     catch (const A* a)  // can catch A
     83     {
     84         assert(a->id_ == 5);
     85         assert(static_cast<const C1*>(a)->id_ == 4);
     86         assert(static_cast<const C2*>(a)->id_ == 3);
     87         assert(static_cast<const B*>(a)->id_ == 8);
     88         throw;
     89     }
     90     catch (const C1*)
     91     {
     92         assert(false);
     93     }
     94     catch (const C2*)
     95     {
     96         assert(false);
     97     }
     98     catch (const B*)
     99     {
    100         assert(false);
    101     }
    102 }
    103 
    104 void f3()
    105 {
    106     try
    107     {
    108         f2();
    109         assert(false);
    110     }
    111     catch (const B* a)  // can catch B
    112     {
    113         assert(static_cast<const B*>(a)->id_ == 8);
    114         throw;
    115     }
    116     catch (const C1* c1)
    117     {
    118         assert(false);
    119     }
    120     catch (const C2*)
    121     {
    122         assert(false);
    123     }
    124 }
    125 
    126 void f4()
    127 {
    128     try
    129     {
    130         f3();
    131         assert(false);
    132     }
    133     catch (const C2* c2)  // can catch C2
    134     {
    135         assert(c2->id_ == 3);
    136         throw;
    137     }
    138     catch (const B* a)
    139     {
    140         assert(false);
    141     }
    142     catch (const C1*)
    143     {
    144         assert(false);
    145     }
    146 }
    147 
    148 void f5()
    149 {
    150     try
    151     {
    152         f4();
    153         assert(false);
    154     }
    155     catch (const C1* c1)  // can catch C1
    156     {
    157         assert(c1->id_ == 4);
    158         assert(static_cast<const B*>(c1)->id_ == 8);
    159         throw;
    160     }
    161     catch (const B* a)
    162     {
    163         assert(false);
    164     }
    165     catch (const C2*)
    166     {
    167         assert(false);
    168     }
    169 }
    170 
    171 int main()
    172 {
    173     try
    174     {
    175         f5();
    176         assert(false);
    177     }
    178     catch (...)
    179     {
    180     }
    181 }
    182