1830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//===---------------------- catch_class_04.cpp ----------------------------===//
2830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//
3830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//                     The LLVM Compiler Infrastructure
4830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//
5830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//
8830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//===----------------------------------------------------------------------===//
9830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
10830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/*
11830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    This test checks that adjustedPtr is correct as there exist offsets in this
12830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    object for the various subobjects, all of which have a unique id_ to
13830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    check against.  It also checks that virtual bases work properly
14830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant*/
15830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
16830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <exception>
17830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdlib.h>
18830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <assert.h>
19830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
20830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct B
21830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
22830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    static int count;
23830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    int id_;
24830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    explicit B(int id) : id_(id) {count++;}
25830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    B(const B& a) : id_(a.id_) {count++;}
26830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    ~B() {count--;}
27830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant};
28830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
29830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint B::count = 0;
30830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
31830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct C1
32830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    : virtual B
33830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
34830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    static int count;
35830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    int id_;
36830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    explicit C1(int id) : B(id-2), id_(id) {count++;}
37830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
38830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    ~C1() {count--;}
39830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant};
40830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
41830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint C1::count = 0;
42830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
43830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct C2
44830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    : virtual private B
45830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
46830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    static int count;
47830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    int id_;
48830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    explicit C2(int id) : B(id-2), id_(id) {count++;}
49830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
50830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    ~C2() {count--;}
51830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant};
52830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
53830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint C2::count = 0;
54830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
55830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct A
56830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    : C1, C2
57830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
58830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    static int count;
59830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    int id_;
60830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;}
61830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;}
62830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    ~A() {count--;}
63830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant};
64830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
65830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint A::count = 0;
66830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
67830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f1()
68830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
69830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(A::count == 0);
70830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C1::count == 0);
71830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C2::count == 0);
72830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(B::count == 0);
73830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    A a(5);
74830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(A::count == 1);
75830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C1::count == 1);
76830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C2::count == 1);
77830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(B::count == 1);
78830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
79830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(a.id_ == 5);
80830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(static_cast<C1&>(a).id_ == 4);
81830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(static_cast<C2&>(a).id_ == 3);
82830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(static_cast<B&>(a).id_ == 8);
83830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    throw a;
84830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(false);
85830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
86830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
87830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f2()
88830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
89830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    try
90830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
91830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(A::count == 0);
92830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C1::count == 0);
93830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C2::count == 0);
94830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(B::count == 0);
95830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        f1();
96830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
97830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
98830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const A& a)  // can catch A
99830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
100830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(a.id_ == 5);
101830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(static_cast<const C1&>(a).id_ == 4);
102830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(static_cast<const C2&>(a).id_ == 3);
103830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(static_cast<const B&>(a).id_ == 8);
104830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        throw;
105830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
106830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C1&)
107830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
108830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
109830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
110830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C2&)
111830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
112830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
113830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
114830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const B&)
115830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
116830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
117830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
118830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
119830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
120830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f3()
121830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
122830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    try
123830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
124830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(A::count == 0);
125830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C1::count == 0);
126830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C2::count == 0);
127830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(B::count == 0);
128830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        f2();
129830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
130830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
131830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const B& a)  // can catch B
132830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
133830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(static_cast<const B&>(a).id_ == 8);
134830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        throw;
135830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
136830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C1& c1)
137830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
138830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
139830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
140830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C2&)
141830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
142830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
143830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
144830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
145830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
146830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f4()
147830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
148830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    try
149830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
150830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(A::count == 0);
151830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C1::count == 0);
152830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C2::count == 0);
153830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(B::count == 0);
154830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        f3();
155830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
156830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
157830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C2& c2)  // can catch C2
158830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
159830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(c2.id_ == 3);
160830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        throw;
161830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
162830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const B& a)  // can not catch B (ambiguous base)
163830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
164830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
165830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
166830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C1&)
167830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
168830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
169830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
170830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
171830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
172830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f5()
173830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
174830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    try
175830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
176830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(A::count == 0);
177830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C1::count == 0);
178830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(C2::count == 0);
179830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(B::count == 0);
180830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        f4();
181830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
182830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
183830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C1& c1)  // can catch C1
184830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
185830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(c1.id_ == 4);
186830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(static_cast<const B&>(c1).id_ == 8);
187830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        throw;
188830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
189830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const B& a)
190830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
191830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
192830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
193830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (const C2&)
194830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
195830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
196830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
197830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
198830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant
199830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint main()
200830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{
201830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    try
202830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
203830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        f5();
204830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant        assert(false);
205830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
206830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    catch (...)
207830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    {
208830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    }
209830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(A::count == 0);
210830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C1::count == 0);
211830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(C2::count == 0);
212830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant    assert(B::count == 0);
213830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}
214