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