1 //===--------------------- 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 30 struct Base { 31 int b1; 32 }; 33 34 struct Base2 { 35 int b2; 36 }; 37 38 struct Child : public Base, public Base2 { 39 int c; 40 }; 41 f1()42void f1() { 43 Child child; 44 child.b1 = 10; 45 child.b2 = 11; 46 child.c = 12; 47 throw child; 48 } 49 f2()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 f3()58void f3() { 59 static Child child; 60 child.b1 = 10; 61 child.b2 = 11; 62 child.c = 12; 63 throw static_cast<Base2*>(&child); 64 } 65 main()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 } 166