forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			166 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--------------------- inherited_exception.cpp ------------------------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is dual licensed under the MIT and the University of Illinois Open
 | |
| // Source Licenses. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2
 | |
| //
 | |
| //  C++ ABI 15.3:
 | |
| //  A handler is a match for an exception object of type E if
 | |
| //  /  *  The handler is of type cv T or cv T& and E and T are the same type   \
 | |
| //  |     (ignoring the top-level cv-qualifiers), or                           |
 | |
| //  |  *  the handler is of type cv T or cv T& and T is an unambiguous base    |
 | |
| //  \     class of E, or                                                       /
 | |
| //     *  the handler is of type cv1 T* cv2 and E is a pointer type that can
 | |
| //        be converted to the type of the handler by either or both of
 | |
| //          o  a standard pointer conversion (4.10 [conv.ptr]) not involving
 | |
| //             conversions to private or protected or ambiguous classes
 | |
| //          o  a qualification conversion
 | |
| //     *  the handler is a pointer or pointer to member type and E is
 | |
| //        std::nullptr_t
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include <assert.h>
 | |
| 
 | |
| struct Base {
 | |
|   int b1;
 | |
| };
 | |
| 
 | |
| struct Base2 {
 | |
|   int b2;
 | |
| };
 | |
| 
 | |
| struct Child : public Base, public Base2 {
 | |
|   int c;
 | |
| };
 | |
| 
 | |
| void f1() {
 | |
|   Child child;
 | |
|   child.b1 = 10;
 | |
|   child.b2 = 11;
 | |
|   child.c = 12;
 | |
|   throw child;
 | |
| }
 | |
| 
 | |
| void f2() {
 | |
|   Child child;
 | |
|   child.b1 = 10;
 | |
|   child.b2 = 11;
 | |
|   child.c = 12;
 | |
|   throw static_cast<Base2&>(child);
 | |
| }
 | |
| 
 | |
| void f3() {
 | |
|   static Child child;
 | |
|   child.b1 = 10;
 | |
|   child.b2 = 11;
 | |
|   child.c = 12;
 | |
|   throw static_cast<Base2*>(&child);
 | |
| }
 | |
| 
 | |
| int main()
 | |
| {
 | |
|     try
 | |
|     {
 | |
|         f1();
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Child& c)
 | |
|     {
 | |
|         assert(true);
 | |
|     }
 | |
|     catch (const Base& b)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (...)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
| 
 | |
|     try
 | |
|     {
 | |
|         f1();
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base& c)
 | |
|     {
 | |
|         assert(true);
 | |
|     }
 | |
|     catch (const Child& b)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (...)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
| 
 | |
|     try
 | |
|     {
 | |
|         f1();
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base2& c)
 | |
|     {
 | |
|         assert(true);
 | |
|     }
 | |
|     catch (const Child& b)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (...)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
| 
 | |
|     try
 | |
|     {
 | |
|         f2();
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Child& c)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base& b)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base2& b)
 | |
|     {
 | |
|         assert(true);
 | |
|     }
 | |
|     catch (...)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
| 
 | |
|     try
 | |
|     {
 | |
|         f3();
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base* c)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Child* b)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
|     catch (const Base2* c)
 | |
|     {
 | |
|         assert(true);
 | |
|     }
 | |
|     catch (...)
 | |
|     {
 | |
|         assert(false);
 | |
|     }
 | |
| }
 |