174 lines · cpp
1//===----------------------------------------------------------------------===//2//3// 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-exception6//7//===----------------------------------------------------------------------===//8//9// This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.210//11// C++ ABI 15.3:12// A handler is a match for an exception object of type E if13// > * 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 can18// be converted to the type of the handler by either or both of19// o a standard pointer conversion (4.10 [conv.ptr]) not involving20// conversions to private or protected or ambiguous classes21// o a qualification conversion22// * the handler is a pointer or pointer to member type and E is23// std::nullptr_t24//25//===----------------------------------------------------------------------===//26 27// UNSUPPORTED: no-exceptions28 29// Compilers emit warnings about exceptions of type 'Child' being caught by30// an earlier handler of type 'Base'. Congrats, you've just diagnosed the31// behavior under test.32// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions33 34#include <assert.h>35 36struct Base {37 int b1;38};39 40struct Base2 {41 int b2;42};43 44struct Child : public Base, public Base2 {45 int c;46};47 48void f1() {49 Child child;50 child.b1 = 10;51 child.b2 = 11;52 child.c = 12;53 throw child;54}55 56void f2() {57 Child child;58 child.b1 = 10;59 child.b2 = 11;60 child.c = 12;61 throw static_cast<Base2&>(child);62}63 64void f3() {65 static Child child;66 child.b1 = 10;67 child.b2 = 11;68 child.c = 12;69 throw static_cast<Base2*>(&child);70}71 72int main(int, char**)73{74 try75 {76 f1();77 assert(false);78 }79 catch (const Child& c)80 {81 assert(true);82 }83 catch (const Base& b)84 {85 assert(false);86 }87 catch (...)88 {89 assert(false);90 }91 92 try93 {94 f1();95 assert(false);96 }97 catch (const Base& c)98 {99 assert(true);100 }101 catch (const Child& b)102 {103 assert(false);104 }105 catch (...)106 {107 assert(false);108 }109 110 try111 {112 f1();113 assert(false);114 }115 catch (const Base2& c)116 {117 assert(true);118 }119 catch (const Child& b)120 {121 assert(false);122 }123 catch (...)124 {125 assert(false);126 }127 128 try129 {130 f2();131 assert(false);132 }133 catch (const Child& c)134 {135 assert(false);136 }137 catch (const Base& b)138 {139 assert(false);140 }141 catch (const Base2& b)142 {143 assert(true);144 }145 catch (...)146 {147 assert(false);148 }149 150 try151 {152 f3();153 assert(false);154 }155 catch (const Base* c)156 {157 assert(false);158 }159 catch (const Child* b)160 {161 assert(false);162 }163 catch (const Base2* c)164 {165 assert(true);166 }167 catch (...)168 {169 assert(false);170 }171 172 return 0;173}174