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