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 
30 struct Base {
31   int b1;
32 };
33 
34 struct Base2 {
35   int b2;
36 };
37 
38 struct Child : public Base, public Base2 {
39   int c;
40 };
41 
f1()42 void f1() {
43   Child child;
44   child.b1 = 10;
45   child.b2 = 11;
46   child.c = 12;
47   throw child;
48 }
49 
f2()50 void f2() {
51   Child child;
52   child.b1 = 10;
53   child.b2 = 11;
54   child.c = 12;
55   throw static_cast<Base2&>(child);
56 }
57 
f3()58 void f3() {
59   static Child child;
60   child.b1 = 10;
61   child.b2 = 11;
62   child.c = 12;
63   throw static_cast<Base2*>(&child);
64 }
65 
main()66 int 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