Home | History | Annotate | Download | only in tests
      1 //===---------------------- catch_class_03.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.
     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     : 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     : 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), id_(id) {count++;}
     61     A(const A& a) : C1(a.id_-1), C2(a.id_-2), 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 == 2);
     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&>(static_cast<C1&>(a)).id_ == 2);
     83     assert(static_cast<B&>(static_cast<C2&>(a)).id_ == 1);
     84     throw a;
     85     assert(false);
     86 }
     87 
     88 void f2()
     89 {
     90     try
     91     {
     92         assert(A::count == 0);
     93         assert(C1::count == 0);
     94         assert(C2::count == 0);
     95         assert(B::count == 0);
     96         f1();
     97         assert(false);
     98     }
     99     catch (const A& a)  // can catch A
    100     {
    101         assert(a.id_ == 5);
    102         assert(static_cast<const C1&>(a).id_ == 4);
    103         assert(static_cast<const C2&>(a).id_ == 3);
    104         assert(static_cast<const B&>(static_cast<const C1&>(a)).id_ == 2);
    105         assert(static_cast<const B&>(static_cast<const C2&>(a)).id_ == 1);
    106         throw;
    107     }
    108     catch (const C1&)
    109     {
    110         assert(false);
    111     }
    112     catch (const C2&)
    113     {
    114         assert(false);
    115     }
    116     catch (const B&)
    117     {
    118         assert(false);
    119     }
    120 }
    121 
    122 void f3()
    123 {
    124     try
    125     {
    126         assert(A::count == 0);
    127         assert(C1::count == 0);
    128         assert(C2::count == 0);
    129         assert(B::count == 0);
    130         f2();
    131         assert(false);
    132     }
    133     catch (const B& a)  // can not catch B (ambiguous base)
    134     {
    135         assert(false);
    136     }
    137     catch (const C1& c1)  // can catch C1
    138     {
    139         assert(c1.id_ == 4);
    140         assert(static_cast<const B&>(c1).id_ == 2);
    141         throw;
    142     }
    143     catch (const C2&)
    144     {
    145         assert(false);
    146     }
    147 }
    148 
    149 void f4()
    150 {
    151     try
    152     {
    153         assert(A::count == 0);
    154         assert(C1::count == 0);
    155         assert(C2::count == 0);
    156         assert(B::count == 0);
    157         f3();
    158         assert(false);
    159     }
    160     catch (const B& a)  // can not catch B (ambiguous base)
    161     {
    162         assert(false);
    163     }
    164     catch (const C2& c2)  // can catch C2
    165     {
    166         assert(c2.id_ == 3);
    167         assert(static_cast<const B&>(c2).id_ == 1);
    168         throw;
    169     }
    170     catch (const C1&)
    171     {
    172         assert(false);
    173     }
    174 }
    175 
    176 int main()
    177 {
    178     try
    179     {
    180         f4();
    181         assert(false);
    182     }
    183     catch (...)
    184     {
    185     }
    186     assert(A::count == 0);
    187     assert(C1::count == 0);
    188     assert(C2::count == 0);
    189     assert(B::count == 0);
    190 }
    191