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_;
BB24     explicit B(int id) : id_(id) {count++;}
BB25     B(const B& a) : id_(a.id_) {count++;}
~BB26     ~B() {count--;}
27 };
28 
29 int B::count = 0;
30 
31 struct C1
32     : virtual B
33 {
34     static int count;
35     int id_;
C1C136     explicit C1(int id) : B(id-2), id_(id) {count++;}
C1C137     C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
~C1C138     ~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_;
C2C248     explicit C2(int id) : B(id-2), id_(id) {count++;}
C2C249     C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
~C2C250     ~C2() {count--;}
51 };
52 
53 int C2::count = 0;
54 
55 struct A
56     : C1, C2
57 {
58     static int count;
59     int id_;
AA60     explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;}
AA61     A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;}
~AA62     ~A() {count--;}
63 };
64 
65 int A::count = 0;
66 
67 A a(5);
68 
f1()69 void f1()
70 {
71     throw &a;
72     assert(false);
73 }
74 
f2()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 
f3()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 
f4()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 
f5()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 
main()171 int main()
172 {
173     try
174     {
175         f5();
176         assert(false);
177     }
178     catch (...)
179     {
180     }
181 }
182