blob: ac92ab4dc6c25667055b3544265dff1dc55ccdc6 [file] [log] [blame]
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +00001//===--------------------- inherited_exception.cpp ------------------------===//
2//
Chandler Carruth57b08b02019-01-19 10:56:40 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
10//
11// C++ ABI 15.3:
12// A handler is a match for an exception object of type E if
13// / * The handler is of type cv T or cv T& and E and T are the same type \
14// | (ignoring the top-level cv-qualifiers), or |
15// | * the handler is of type cv T or cv T& and T is an unambiguous base |
16// \ class of E, or /
17// * the handler is of type cv1 T* cv2 and E is a pointer type that can
18// be converted to the type of the handler by either or both of
19// o a standard pointer conversion (4.10 [conv.ptr]) not involving
20// conversions to private or protected or ambiguous classes
21// o a qualification conversion
22// * the handler is a pointer or pointer to member type and E is
23// std::nullptr_t
24//
25//===----------------------------------------------------------------------===//
26
Louis Dionne8c611142020-04-17 10:29:15 -040027// UNSUPPORTED: no-exceptions
Asiri Rathnayake57e446d2016-05-31 12:01:32 +000028
Eric Fiselierf5ff11c2016-06-15 19:07:19 +000029// Clang emits warnings about exceptions of type 'Child' being caught by
30// an earlier handler of type 'Base'. Congrats clang, you've just
31// diagnosed the behavior under test.
32#if defined(__clang__)
33#pragma clang diagnostic ignored "-Wexceptions"
34#endif
35
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000036#include <assert.h>
37
38struct Base {
39 int b1;
40};
41
42struct Base2 {
43 int b2;
44};
45
46struct Child : public Base, public Base2 {
47 int c;
48};
49
50void f1() {
51 Child child;
52 child.b1 = 10;
53 child.b2 = 11;
54 child.c = 12;
55 throw child;
56}
57
58void f2() {
59 Child child;
60 child.b1 = 10;
61 child.b2 = 11;
62 child.c = 12;
63 throw static_cast<Base2&>(child);
64}
65
66void f3() {
Eric Fiseliera3158652014-11-21 01:53:51 +000067 static Child child;
68 child.b1 = 10;
69 child.b2 = 11;
70 child.c = 12;
71 throw static_cast<Base2*>(&child);
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000072}
73
74int main()
75{
76 try
77 {
78 f1();
79 assert(false);
80 }
81 catch (const Child& c)
82 {
83 assert(true);
84 }
85 catch (const Base& b)
86 {
87 assert(false);
88 }
89 catch (...)
90 {
91 assert(false);
92 }
93
94 try
95 {
96 f1();
97 assert(false);
98 }
99 catch (const Base& c)
100 {
101 assert(true);
102 }
103 catch (const Child& b)
104 {
105 assert(false);
106 }
107 catch (...)
108 {
109 assert(false);
110 }
111
112 try
113 {
114 f1();
115 assert(false);
116 }
117 catch (const Base2& c)
118 {
119 assert(true);
120 }
121 catch (const Child& b)
122 {
123 assert(false);
124 }
125 catch (...)
126 {
127 assert(false);
128 }
129
130 try
131 {
132 f2();
133 assert(false);
134 }
135 catch (const Child& c)
136 {
137 assert(false);
138 }
139 catch (const Base& b)
140 {
141 assert(false);
142 }
143 catch (const Base2& b)
144 {
145 assert(true);
146 }
147 catch (...)
148 {
149 assert(false);
150 }
151
152 try
153 {
154 f3();
155 assert(false);
156 }
157 catch (const Base* c)
158 {
159 assert(false);
160 }
161 catch (const Child* b)
162 {
163 assert(false);
164 }
165 catch (const Base2* c)
166 {
167 assert(true);
168 }
169 catch (...)
170 {
171 assert(false);
172 }
173}