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_;
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     : 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     : 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), id_(id) {count++;}
AA61     A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
~AA62     ~A() {count--;}
63 };
64 
65 int A::count = 0;
66 
f1()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 
f2()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 
f3()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 
f4()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 
main()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