blob: 7c106c1e612378ad7b7afc8d069adca709095748 [file] [log] [blame]
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +00001//===--------------------- 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() {
Eric Fiseliera3158652014-11-21 01:53:51 +000059 static Child child;
60 child.b1 = 10;
61 child.b2 = 11;
62 child.c = 12;
63 throw static_cast<Base2*>(&child);
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000064}
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}