1*eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
2e434b34fSJonathan Roelofs //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e434b34fSJonathan Roelofs //
7e434b34fSJonathan Roelofs //===----------------------------------------------------------------------===//
8e434b34fSJonathan Roelofs
9e434b34fSJonathan Roelofs /*
10e434b34fSJonathan Roelofs This test checks that adjustedPtr is correct as there exist offsets in this
11e434b34fSJonathan Roelofs object for the various subobjects, all of which have a unique id_ to
12e434b34fSJonathan Roelofs check against. It also checks that virtual bases work properly
13e434b34fSJonathan Roelofs */
14e434b34fSJonathan Roelofs
158c61114cSLouis Dionne // UNSUPPORTED: no-exceptions
1657e446daSAsiri Rathnayake
17d9eb6c7cSLouis Dionne // Compilers emit warnings about exceptions of type 'Child' being caught by
18d9eb6c7cSLouis Dionne // an earlier handler of type 'Base'. Congrats, you've just diagnosed the
19d9eb6c7cSLouis Dionne // behavior under test.
20d9eb6c7cSLouis Dionne // ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions
218d313927SLouis Dionne
22e434b34fSJonathan Roelofs #include <exception>
23e434b34fSJonathan Roelofs #include <stdlib.h>
24e434b34fSJonathan Roelofs #include <assert.h>
25e434b34fSJonathan Roelofs
26e434b34fSJonathan Roelofs struct B
27e434b34fSJonathan Roelofs {
28e434b34fSJonathan Roelofs static int count;
29e434b34fSJonathan Roelofs int id_;
BB30e434b34fSJonathan Roelofs explicit B(int id) : id_(id) {count++;}
BB31e434b34fSJonathan Roelofs B(const B& a) : id_(a.id_) {count++;}
~BB32e434b34fSJonathan Roelofs ~B() {count--;}
33e434b34fSJonathan Roelofs };
34e434b34fSJonathan Roelofs
35e434b34fSJonathan Roelofs int B::count = 0;
36e434b34fSJonathan Roelofs
37e434b34fSJonathan Roelofs struct C1
38e434b34fSJonathan Roelofs : virtual B
39e434b34fSJonathan Roelofs {
40e434b34fSJonathan Roelofs static int count;
41e434b34fSJonathan Roelofs int id_;
C1C142e434b34fSJonathan Roelofs explicit C1(int id) : B(id-2), id_(id) {count++;}
C1C143e434b34fSJonathan Roelofs C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
~C1C144e434b34fSJonathan Roelofs ~C1() {count--;}
45e434b34fSJonathan Roelofs };
46e434b34fSJonathan Roelofs
47e434b34fSJonathan Roelofs int C1::count = 0;
48e434b34fSJonathan Roelofs
49e434b34fSJonathan Roelofs struct C2
50e434b34fSJonathan Roelofs : virtual private B
51e434b34fSJonathan Roelofs {
52e434b34fSJonathan Roelofs static int count;
53e434b34fSJonathan Roelofs int id_;
C2C254e434b34fSJonathan Roelofs explicit C2(int id) : B(id-2), id_(id) {count++;}
C2C255e434b34fSJonathan Roelofs C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
~C2C256e434b34fSJonathan Roelofs ~C2() {count--;}
57e434b34fSJonathan Roelofs };
58e434b34fSJonathan Roelofs
59e434b34fSJonathan Roelofs int C2::count = 0;
60e434b34fSJonathan Roelofs
61e434b34fSJonathan Roelofs struct A
62e434b34fSJonathan Roelofs : C1, C2
63e434b34fSJonathan Roelofs {
64e434b34fSJonathan Roelofs static int count;
65e434b34fSJonathan Roelofs int id_;
AA6678621e40SEric Fiselier explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;}
AA6778621e40SEric Fiselier A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
~AA68e434b34fSJonathan Roelofs ~A() {count--;}
69e434b34fSJonathan Roelofs };
70e434b34fSJonathan Roelofs
71e434b34fSJonathan Roelofs int A::count = 0;
72e434b34fSJonathan Roelofs
f1()73e434b34fSJonathan Roelofs void f1()
74e434b34fSJonathan Roelofs {
75e434b34fSJonathan Roelofs assert(A::count == 0);
76e434b34fSJonathan Roelofs assert(C1::count == 0);
77e434b34fSJonathan Roelofs assert(C2::count == 0);
78e434b34fSJonathan Roelofs assert(B::count == 0);
79e434b34fSJonathan Roelofs A a(5);
80e434b34fSJonathan Roelofs assert(A::count == 1);
81e434b34fSJonathan Roelofs assert(C1::count == 1);
82e434b34fSJonathan Roelofs assert(C2::count == 1);
83e434b34fSJonathan Roelofs assert(B::count == 1);
84e434b34fSJonathan Roelofs
85e434b34fSJonathan Roelofs assert(a.id_ == 5);
86e434b34fSJonathan Roelofs assert(static_cast<C1&>(a).id_ == 4);
87e434b34fSJonathan Roelofs assert(static_cast<C2&>(a).id_ == 3);
88e434b34fSJonathan Roelofs assert(static_cast<B&>(a).id_ == 8);
89e434b34fSJonathan Roelofs throw a;
90e434b34fSJonathan Roelofs assert(false);
91e434b34fSJonathan Roelofs }
92e434b34fSJonathan Roelofs
f2()93e434b34fSJonathan Roelofs void f2()
94e434b34fSJonathan Roelofs {
95e434b34fSJonathan Roelofs try
96e434b34fSJonathan Roelofs {
97e434b34fSJonathan Roelofs assert(A::count == 0);
98e434b34fSJonathan Roelofs assert(C1::count == 0);
99e434b34fSJonathan Roelofs assert(C2::count == 0);
100e434b34fSJonathan Roelofs assert(B::count == 0);
101e434b34fSJonathan Roelofs f1();
102e434b34fSJonathan Roelofs assert(false);
103e434b34fSJonathan Roelofs }
104e434b34fSJonathan Roelofs catch (const A& a) // can catch A
105e434b34fSJonathan Roelofs {
106e434b34fSJonathan Roelofs assert(a.id_ == 5);
107e434b34fSJonathan Roelofs assert(static_cast<const C1&>(a).id_ == 4);
108e434b34fSJonathan Roelofs assert(static_cast<const C2&>(a).id_ == 3);
109e434b34fSJonathan Roelofs assert(static_cast<const B&>(a).id_ == 8);
110e434b34fSJonathan Roelofs throw;
111e434b34fSJonathan Roelofs }
112e434b34fSJonathan Roelofs catch (const C1&)
113e434b34fSJonathan Roelofs {
114e434b34fSJonathan Roelofs assert(false);
115e434b34fSJonathan Roelofs }
116e434b34fSJonathan Roelofs catch (const C2&)
117e434b34fSJonathan Roelofs {
118e434b34fSJonathan Roelofs assert(false);
119e434b34fSJonathan Roelofs }
120e434b34fSJonathan Roelofs catch (const B&)
121e434b34fSJonathan Roelofs {
122e434b34fSJonathan Roelofs assert(false);
123e434b34fSJonathan Roelofs }
124e434b34fSJonathan Roelofs }
125e434b34fSJonathan Roelofs
f3()126e434b34fSJonathan Roelofs void f3()
127e434b34fSJonathan Roelofs {
128e434b34fSJonathan Roelofs try
129e434b34fSJonathan Roelofs {
130e434b34fSJonathan Roelofs assert(A::count == 0);
131e434b34fSJonathan Roelofs assert(C1::count == 0);
132e434b34fSJonathan Roelofs assert(C2::count == 0);
133e434b34fSJonathan Roelofs assert(B::count == 0);
134e434b34fSJonathan Roelofs f2();
135e434b34fSJonathan Roelofs assert(false);
136e434b34fSJonathan Roelofs }
137e434b34fSJonathan Roelofs catch (const B& a) // can catch B
138e434b34fSJonathan Roelofs {
139e434b34fSJonathan Roelofs assert(static_cast<const B&>(a).id_ == 8);
140e434b34fSJonathan Roelofs throw;
141e434b34fSJonathan Roelofs }
142e434b34fSJonathan Roelofs catch (const C1& c1)
143e434b34fSJonathan Roelofs {
144e434b34fSJonathan Roelofs assert(false);
145e434b34fSJonathan Roelofs }
146e434b34fSJonathan Roelofs catch (const C2&)
147e434b34fSJonathan Roelofs {
148e434b34fSJonathan Roelofs assert(false);
149e434b34fSJonathan Roelofs }
150e434b34fSJonathan Roelofs }
151e434b34fSJonathan Roelofs
f4()152e434b34fSJonathan Roelofs void f4()
153e434b34fSJonathan Roelofs {
154e434b34fSJonathan Roelofs try
155e434b34fSJonathan Roelofs {
156e434b34fSJonathan Roelofs assert(A::count == 0);
157e434b34fSJonathan Roelofs assert(C1::count == 0);
158e434b34fSJonathan Roelofs assert(C2::count == 0);
159e434b34fSJonathan Roelofs assert(B::count == 0);
160e434b34fSJonathan Roelofs f3();
161e434b34fSJonathan Roelofs assert(false);
162e434b34fSJonathan Roelofs }
163e434b34fSJonathan Roelofs catch (const C2& c2) // can catch C2
164e434b34fSJonathan Roelofs {
165e434b34fSJonathan Roelofs assert(c2.id_ == 3);
166e434b34fSJonathan Roelofs throw;
167e434b34fSJonathan Roelofs }
168e434b34fSJonathan Roelofs catch (const B& a) // can not catch B (ambiguous base)
169e434b34fSJonathan Roelofs {
170e434b34fSJonathan Roelofs assert(false);
171e434b34fSJonathan Roelofs }
172e434b34fSJonathan Roelofs catch (const C1&)
173e434b34fSJonathan Roelofs {
174e434b34fSJonathan Roelofs assert(false);
175e434b34fSJonathan Roelofs }
176e434b34fSJonathan Roelofs }
177e434b34fSJonathan Roelofs
f5()178e434b34fSJonathan Roelofs void f5()
179e434b34fSJonathan Roelofs {
180e434b34fSJonathan Roelofs try
181e434b34fSJonathan Roelofs {
182e434b34fSJonathan Roelofs assert(A::count == 0);
183e434b34fSJonathan Roelofs assert(C1::count == 0);
184e434b34fSJonathan Roelofs assert(C2::count == 0);
185e434b34fSJonathan Roelofs assert(B::count == 0);
186e434b34fSJonathan Roelofs f4();
187e434b34fSJonathan Roelofs assert(false);
188e434b34fSJonathan Roelofs }
189e434b34fSJonathan Roelofs catch (const C1& c1) // can catch C1
190e434b34fSJonathan Roelofs {
191e434b34fSJonathan Roelofs assert(c1.id_ == 4);
192e434b34fSJonathan Roelofs assert(static_cast<const B&>(c1).id_ == 8);
193e434b34fSJonathan Roelofs throw;
194e434b34fSJonathan Roelofs }
195e434b34fSJonathan Roelofs catch (const B& a)
196e434b34fSJonathan Roelofs {
197e434b34fSJonathan Roelofs assert(false);
198e434b34fSJonathan Roelofs }
199e434b34fSJonathan Roelofs catch (const C2&)
200e434b34fSJonathan Roelofs {
201e434b34fSJonathan Roelofs assert(false);
202e434b34fSJonathan Roelofs }
203e434b34fSJonathan Roelofs }
204e434b34fSJonathan Roelofs
main(int,char **)205504bc07dSLouis Dionne int main(int, char**)
206e434b34fSJonathan Roelofs {
207e434b34fSJonathan Roelofs try
208e434b34fSJonathan Roelofs {
209e434b34fSJonathan Roelofs f5();
210e434b34fSJonathan Roelofs assert(false);
211e434b34fSJonathan Roelofs }
212e434b34fSJonathan Roelofs catch (...)
213e434b34fSJonathan Roelofs {
214e434b34fSJonathan Roelofs }
215e434b34fSJonathan Roelofs assert(A::count == 0);
216e434b34fSJonathan Roelofs assert(C1::count == 0);
217e434b34fSJonathan Roelofs assert(C2::count == 0);
218e434b34fSJonathan Roelofs assert(B::count == 0);
219504bc07dSLouis Dionne
220504bc07dSLouis Dionne return 0;
221e434b34fSJonathan Roelofs }
222