1//===--------------------- inherited_exception.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// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
11//
12//  C++ ABI 15.3:
13//  A handler is a match for an exception object of type E if
14//  /  *  The handler is of type cv T or cv T& and E and T are the same type   \
15//  |     (ignoring the top-level cv-qualifiers), or                           |
16//  |  *  the handler is of type cv T or cv T& and T is an unambiguous base    |
17//  \     class of E, or                                                       /
18//     *  the handler is of type cv1 T* cv2 and E is a pointer type that can
19//        be converted to the type of the handler by either or both of
20//          o  a standard pointer conversion (4.10 [conv.ptr]) not involving
21//             conversions to private or protected or ambiguous classes
22//          o  a qualification conversion
23//     *  the handler is a pointer or pointer to member type and E is
24//        std::nullptr_t
25//
26//===----------------------------------------------------------------------===//
27
28#include <assert.h>
29
30struct Base {
31  int b1;
32};
33
34struct Base2 {
35  int b2;
36};
37
38struct Child : public Base, public Base2 {
39  int c;
40};
41
42void f1() {
43  Child child;
44  child.b1 = 10;
45  child.b2 = 11;
46  child.c = 12;
47  throw child;
48}
49
50void f2() {
51  Child child;
52  child.b1 = 10;
53  child.b2 = 11;
54  child.c = 12;
55  throw static_cast<Base2&>(child);
56}
57
58void f3() {
59  Child* child  = new Child;
60  child->b1 = 10;
61  child->b2 = 11;
62  child->c = 12;
63  throw static_cast<Base2*>(child);
64}
65
66int main()
67{
68    try
69    {
70        f1();
71        assert(false);
72    }
73    catch (const Child& c)
74    {
75        assert(true);
76    }
77    catch (const Base& b)
78    {
79        assert(false);
80    }
81    catch (...)
82    {
83        assert(false);
84    }
85
86    try
87    {
88        f1();
89        assert(false);
90    }
91    catch (const Base& c)
92    {
93        assert(true);
94    }
95    catch (const Child& b)
96    {
97        assert(false);
98    }
99    catch (...)
100    {
101        assert(false);
102    }
103
104    try
105    {
106        f1();
107        assert(false);
108    }
109    catch (const Base2& c)
110    {
111        assert(true);
112    }
113    catch (const Child& b)
114    {
115        assert(false);
116    }
117    catch (...)
118    {
119        assert(false);
120    }
121
122    try
123    {
124        f2();
125        assert(false);
126    }
127    catch (const Child& c)
128    {
129        assert(false);
130    }
131    catch (const Base& b)
132    {
133        assert(false);
134    }
135    catch (const Base2& b)
136    {
137        assert(true);
138    }
139    catch (...)
140    {
141        assert(false);
142    }
143
144    try
145    {
146        f3();
147        assert(false);
148    }
149    catch (const Base* c)
150    {
151        assert(false);
152    }
153    catch (const Child* b)
154    {
155        assert(false);
156    }
157    catch (const Base2* c)
158    {
159        assert(true);
160    }
161    catch (...)
162    {
163        assert(false);
164    }
165}
166