blob: 993c83c82fea7c9322ff97a2648907024ea364d0 [file] [log] [blame]
Jonathan Roelofse53a8f32014-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
Asiri Rathnayake4174e8b2016-05-31 12:01:32 +000028// UNSUPPORTED: libcxxabi-no-exceptions
29
Eric Fiselierdf448d82016-06-15 19:07:19 +000030// Clang emits warnings about exceptions of type 'Child' being caught by
31// an earlier handler of type 'Base'. Congrats clang, you've just
32// diagnosed the behavior under test.
33#if defined(__clang__)
34#pragma clang diagnostic ignored "-Wexceptions"
35#endif
36
Jonathan Roelofse53a8f32014-06-03 21:50:11 +000037#include <assert.h>
38
39struct Base {
40 int b1;
41};
42
43struct Base2 {
44 int b2;
45};
46
47struct Child : public Base, public Base2 {
48 int c;
49};
50
51void f1() {
52 Child child;
53 child.b1 = 10;
54 child.b2 = 11;
55 child.c = 12;
56 throw child;
57}
58
59void f2() {
60 Child child;
61 child.b1 = 10;
62 child.b2 = 11;
63 child.c = 12;
64 throw static_cast<Base2&>(child);
65}
66
67void f3() {
Eric Fiselier6e50cba2014-11-21 01:53:51 +000068 static Child child;
69 child.b1 = 10;
70 child.b2 = 11;
71 child.c = 12;
72 throw static_cast<Base2*>(&child);
Jonathan Roelofse53a8f32014-06-03 21:50:11 +000073}
74
75int main()
76{
77 try
78 {
79 f1();
80 assert(false);
81 }
82 catch (const Child& c)
83 {
84 assert(true);
85 }
86 catch (const Base& b)
87 {
88 assert(false);
89 }
90 catch (...)
91 {
92 assert(false);
93 }
94
95 try
96 {
97 f1();
98 assert(false);
99 }
100 catch (const Base& c)
101 {
102 assert(true);
103 }
104 catch (const Child& b)
105 {
106 assert(false);
107 }
108 catch (...)
109 {
110 assert(false);
111 }
112
113 try
114 {
115 f1();
116 assert(false);
117 }
118 catch (const Base2& c)
119 {
120 assert(true);
121 }
122 catch (const Child& b)
123 {
124 assert(false);
125 }
126 catch (...)
127 {
128 assert(false);
129 }
130
131 try
132 {
133 f2();
134 assert(false);
135 }
136 catch (const Child& c)
137 {
138 assert(false);
139 }
140 catch (const Base& b)
141 {
142 assert(false);
143 }
144 catch (const Base2& b)
145 {
146 assert(true);
147 }
148 catch (...)
149 {
150 assert(false);
151 }
152
153 try
154 {
155 f3();
156 assert(false);
157 }
158 catch (const Base* c)
159 {
160 assert(false);
161 }
162 catch (const Child* b)
163 {
164 assert(false);
165 }
166 catch (const Base2* c)
167 {
168 assert(true);
169 }
170 catch (...)
171 {
172 assert(false);
173 }
174}