blob: ab3fc0785b58d9bc296d6f4a7cebf6ff98213b9e [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
Louis Dionne8d313922020-10-30 17:33:02 -040013// > * 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 <
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000017// * 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
Louis Dionne8d313922020-10-30 17:33:02 -040029// FIXME: GCC doesn't allow turning off the warning for exceptions being caught
30// by earlier handlers, which this test is exercising. We have to disable
31// warnings altogether to remove the error.
32// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97675.
33// ADDITIONAL_COMPILE_FLAGS: -Wno-error
34
Eric Fiselierf5ff11c2016-06-15 19:07:19 +000035// Clang emits warnings about exceptions of type 'Child' being caught by
36// an earlier handler of type 'Base'. Congrats clang, you've just
37// diagnosed the behavior under test.
38#if defined(__clang__)
39#pragma clang diagnostic ignored "-Wexceptions"
40#endif
41
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000042#include <assert.h>
43
44struct Base {
45 int b1;
46};
47
48struct Base2 {
49 int b2;
50};
51
52struct Child : public Base, public Base2 {
53 int c;
54};
55
56void f1() {
57 Child child;
58 child.b1 = 10;
59 child.b2 = 11;
60 child.c = 12;
61 throw child;
62}
63
64void f2() {
65 Child child;
66 child.b1 = 10;
67 child.b2 = 11;
68 child.c = 12;
69 throw static_cast<Base2&>(child);
70}
71
72void f3() {
Eric Fiseliera3158652014-11-21 01:53:51 +000073 static Child child;
74 child.b1 = 10;
75 child.b2 = 11;
76 child.c = 12;
77 throw static_cast<Base2*>(&child);
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000078}
79
Louis Dionne504bc072020-10-08 13:36:33 -040080int main(int, char**)
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +000081{
82 try
83 {
84 f1();
85 assert(false);
86 }
87 catch (const Child& c)
88 {
89 assert(true);
90 }
91 catch (const Base& b)
92 {
93 assert(false);
94 }
95 catch (...)
96 {
97 assert(false);
98 }
99
100 try
101 {
102 f1();
103 assert(false);
104 }
105 catch (const Base& c)
106 {
107 assert(true);
108 }
109 catch (const Child& b)
110 {
111 assert(false);
112 }
113 catch (...)
114 {
115 assert(false);
116 }
117
118 try
119 {
120 f1();
121 assert(false);
122 }
123 catch (const Base2& c)
124 {
125 assert(true);
126 }
127 catch (const Child& b)
128 {
129 assert(false);
130 }
131 catch (...)
132 {
133 assert(false);
134 }
135
136 try
137 {
138 f2();
139 assert(false);
140 }
141 catch (const Child& c)
142 {
143 assert(false);
144 }
145 catch (const Base& b)
146 {
147 assert(false);
148 }
149 catch (const Base2& b)
150 {
151 assert(true);
152 }
153 catch (...)
154 {
155 assert(false);
156 }
157
158 try
159 {
160 f3();
161 assert(false);
162 }
163 catch (const Base* c)
164 {
165 assert(false);
166 }
167 catch (const Child* b)
168 {
169 assert(false);
170 }
171 catch (const Base2* c)
172 {
173 assert(true);
174 }
175 catch (...)
176 {
177 assert(false);
178 }
Louis Dionne504bc072020-10-08 13:36:33 -0400179
180 return 0;
Jonathan Roelofs72a15cd2014-06-03 21:50:11 +0000181}