|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | //  This test case checks specifically the cases under bullet 3.1 & 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 | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | // UNSUPPORTED: no-exceptions | 
|  |  | 
|  | #include <exception> | 
|  | #include <stdlib.h> | 
|  | #include <assert.h> | 
|  | #include <stdio.h> | 
|  |  | 
|  | struct Base {}; | 
|  | struct Derived  : Base {}; | 
|  | struct Derived2 : Base {}; | 
|  | struct Ambiguous : Derived, Derived2 {}; | 
|  | struct Private : private Base {}; | 
|  | struct Protected : protected Base {}; | 
|  |  | 
|  | template <typename T  // Handler type | 
|  | ,typename E  // Thrown exception type | 
|  | ,typename O  // Object type | 
|  | > | 
|  | void assert_catches() | 
|  | { | 
|  | try | 
|  | { | 
|  | O o; | 
|  | throw static_cast<E>(&o); | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "Statements after throw must be unreachable"); | 
|  | } | 
|  | catch (T t) | 
|  | { | 
|  | assert(true); | 
|  | return; | 
|  | } | 
|  | catch (...) | 
|  | { | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "Should not have entered catch-all"); | 
|  | } | 
|  |  | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "The catch should have returned"); | 
|  | } | 
|  |  | 
|  | template <typename T  // Handler type | 
|  | ,typename E  // Thrown exception type | 
|  | ,typename O  // Object type | 
|  | > | 
|  | void assert_cannot_catch() | 
|  | { | 
|  | try | 
|  | { | 
|  | O o; | 
|  | throw static_cast<E>(&o); | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "Statements after throw must be unreachable"); | 
|  | } | 
|  | catch (T t) | 
|  | { | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "Should not have entered the catch"); | 
|  | } | 
|  | catch (...) | 
|  | { | 
|  | assert(true); | 
|  | return; | 
|  | } | 
|  |  | 
|  | printf("%s\n", __PRETTY_FUNCTION__); | 
|  | assert(false && "The catch-all should have returned"); | 
|  | } | 
|  |  | 
|  | void f1() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Base * cv2 | 
|  | // catches an exception of type: | 
|  | //   Derived * | 
|  | assert_catches<               Base *               , Derived *, Derived>(); | 
|  | assert_catches<const          Base *               , Derived *, Derived>(); | 
|  | assert_catches<      volatile Base *               , Derived *, Derived>(); | 
|  | assert_catches<const volatile Base *               , Derived *, Derived>(); | 
|  | assert_catches<               Base * const         , Derived *, Derived>(); | 
|  | assert_catches<const          Base * const         , Derived *, Derived>(); | 
|  | assert_catches<      volatile Base * const         , Derived *, Derived>(); | 
|  | assert_catches<const volatile Base * const         , Derived *, Derived>(); | 
|  | assert_catches<               Base *       volatile, Derived *, Derived>(); | 
|  | assert_catches<const          Base *       volatile, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base *       volatile, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base *       volatile, Derived *, Derived>(); | 
|  | assert_catches<               Base * const volatile, Derived *, Derived>(); | 
|  | assert_catches<const          Base * const volatile, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base * const volatile, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base * const volatile, Derived *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f2() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Base * cv2 | 
|  | // catches an exception of type: | 
|  | //   Base * | 
|  | assert_catches<               Base *               , Base *, Derived>(); | 
|  | assert_catches<const          Base *               , Base *, Derived>(); | 
|  | assert_catches<      volatile Base *               , Base *, Derived>(); | 
|  | assert_catches<const volatile Base *               , Base *, Derived>(); | 
|  | assert_catches<               Base * const         , Base *, Derived>(); | 
|  | assert_catches<const          Base * const         , Base *, Derived>(); | 
|  | assert_catches<      volatile Base * const         , Base *, Derived>(); | 
|  | assert_catches<const volatile Base * const         , Base *, Derived>(); | 
|  | assert_catches<               Base *       volatile, Base *, Derived>(); | 
|  | assert_catches<const          Base *       volatile, Base *, Derived>(); | 
|  | assert_catches<      volatile Base *       volatile, Base *, Derived>(); | 
|  | assert_catches<const volatile Base *       volatile, Base *, Derived>(); | 
|  | assert_catches<               Base * const volatile, Base *, Derived>(); | 
|  | assert_catches<const          Base * const volatile, Base *, Derived>(); | 
|  | assert_catches<      volatile Base * const volatile, Base *, Derived>(); | 
|  | assert_catches<const volatile Base * const volatile, Base *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f3() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Derived * cv2 | 
|  | // catches an exception of type: | 
|  | //   Derived * | 
|  | assert_catches<               Derived *               , Derived *, Derived>(); | 
|  | assert_catches<const          Derived *               , Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived *               , Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived *               , Derived *, Derived>(); | 
|  | assert_catches<               Derived * const         , Derived *, Derived>(); | 
|  | assert_catches<const          Derived * const         , Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived * const         , Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived * const         , Derived *, Derived>(); | 
|  | assert_catches<               Derived *       volatile, Derived *, Derived>(); | 
|  | assert_catches<const          Derived *       volatile, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived *       volatile, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived *       volatile, Derived *, Derived>(); | 
|  | assert_catches<               Derived * const volatile, Derived *, Derived>(); | 
|  | assert_catches<const          Derived * const volatile, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived * const volatile, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived * const volatile, Derived *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f4() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Derived * cv2 | 
|  | // cannot catch an exception of type: | 
|  | //   Base * | 
|  | assert_cannot_catch<               Derived *               , Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived *               , Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived *               , Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived *               , Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived * const         , Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived * const         , Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived * const         , Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived * const         , Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived *       volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived *       volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived *       volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived *       volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived * const volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived * const volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived * const volatile, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived * const volatile, Base *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f5() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Derived * cv2 & | 
|  | // catches an exception of type: | 
|  | //   Derived * | 
|  | assert_catches<               Derived *                &, Derived *, Derived>(); | 
|  | assert_catches<const          Derived *                &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived *                &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived *                &, Derived *, Derived>(); | 
|  | assert_catches<               Derived * const          &, Derived *, Derived>(); | 
|  | assert_catches<const          Derived * const          &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived * const          &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived * const          &, Derived *, Derived>(); | 
|  | assert_catches<               Derived *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<const          Derived *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<               Derived * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<const          Derived * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Derived * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Derived * const volatile &, Derived *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f6() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Base * cv2 & | 
|  | // catches an exception of type: | 
|  | //   Base * | 
|  | assert_catches<               Base *                &, Base *, Derived>(); | 
|  | assert_catches<const          Base *                &, Base *, Derived>(); | 
|  | assert_catches<      volatile Base *                &, Base *, Derived>(); | 
|  | assert_catches<const volatile Base *                &, Base *, Derived>(); | 
|  | assert_catches<               Base * const          &, Base *, Derived>(); | 
|  | assert_catches<const          Base * const          &, Base *, Derived>(); | 
|  | assert_catches<      volatile Base * const          &, Base *, Derived>(); | 
|  | assert_catches<const volatile Base * const          &, Base *, Derived>(); | 
|  | assert_catches<               Base *       volatile &, Base *, Derived>(); | 
|  | assert_catches<const          Base *       volatile &, Base *, Derived>(); | 
|  | assert_catches<      volatile Base *       volatile &, Base *, Derived>(); | 
|  | assert_catches<const volatile Base *       volatile &, Base *, Derived>(); | 
|  | assert_catches<               Base * const volatile &, Base *, Derived>(); | 
|  | assert_catches<const          Base * const volatile &, Base *, Derived>(); | 
|  | assert_catches<      volatile Base * const volatile &, Base *, Derived>(); | 
|  | assert_catches<const volatile Base * const volatile &, Base *, Derived>(); | 
|  |  | 
|  | } | 
|  |  | 
|  | void f7() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Derived * cv2 & | 
|  | // cannot catch an exception of type: | 
|  | //   Base * | 
|  | assert_cannot_catch<               Derived *                &, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived *                &, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived *                &, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived *                &, Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived * const          &, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived * const          &, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived * const          &, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived * const          &, Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived *       volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived *       volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived *       volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived *       volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<               Derived * const volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<const          Derived * const volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<      volatile Derived * const volatile &, Base *, Derived>(); | 
|  | assert_cannot_catch<const volatile Derived * const volatile &, Base *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f8() | 
|  | { | 
|  | // This test case has a caveat noted in the discussion here: | 
|  | //   https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html | 
|  | // Specifically: | 
|  | //   This [test exposes a] corner case of the ARM C++ ABI. The generic C++ | 
|  | //   ABI also gets this wrong, because I failed to notice the subtlety here. | 
|  | //   The issue is that 15.3/3 3rd bullet says: | 
|  | //     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: | 
|  | //       * a standard pointer conversion (4.10) not involving conversions | 
|  | //         to pointers to private or protected or ambiguous classes | 
|  | //   Notice that the handlers of type "cv1 T*cv2&" are not allowed such | 
|  | //   freedom to find a base class. The ABI error is that we treat handlers | 
|  | //   of reference type exactly the same as the corresponding hander of | 
|  | //   non-reference type. Elsewhere in the exception handling this makes no | 
|  | //   difference (for instance bullet 1 explicitly says 'cv T or cv T&'). | 
|  | // | 
|  | // See also: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#388 | 
|  | // | 
|  | //  TL;DR: it is an unresolved C++ ABI defect that these do catch | 
|  |  | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Base * cv2 & | 
|  | // catches an exception of type: | 
|  | //   Derived * | 
|  | assert_catches<               Base *                &, Derived *, Derived>(); | 
|  | assert_catches<const          Base *                &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base *                &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base *                &, Derived *, Derived>(); | 
|  | assert_catches<               Base * const          &, Derived *, Derived>(); | 
|  | assert_catches<const          Base * const          &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base * const          &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base * const          &, Derived *, Derived>(); | 
|  | assert_catches<               Base *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<const          Base *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base *       volatile &, Derived *, Derived>(); | 
|  | assert_catches<               Base * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<const          Base * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<      volatile Base * const volatile &, Derived *, Derived>(); | 
|  | assert_catches<const volatile Base * const volatile &, Derived *, Derived>(); | 
|  | } | 
|  |  | 
|  | void f9() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //   cv1 Base * cv2 | 
|  | // cannot catch an exception of type: | 
|  | //   Ambiguous * | 
|  | assert_cannot_catch<               Base *               , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const          Base *               , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<      volatile Base *               , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const volatile Base *               , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<               Base * const         , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const          Base * const         , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<      volatile Base * const         , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const volatile Base * const         , Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<               Base *       volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const          Base *       volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<      volatile Base *       volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const volatile Base *       volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<               Base * const volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const          Base * const volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<      volatile Base * const volatile, Ambiguous *, Ambiguous>(); | 
|  | assert_cannot_catch<const volatile Base * const volatile, Ambiguous *, Ambiguous>(); | 
|  | } | 
|  |  | 
|  | void f10() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //  cv1 Base * cv2 | 
|  | // cannot catch an exception of type: | 
|  | //  Private * | 
|  | assert_cannot_catch<               Base *               , Private *, Private>(); | 
|  | assert_cannot_catch<const          Base *               , Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base *               , Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base *               , Private *, Private>(); | 
|  | assert_cannot_catch<               Base * const         , Private *, Private>(); | 
|  | assert_cannot_catch<const          Base * const         , Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base * const         , Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base * const         , Private *, Private>(); | 
|  | assert_cannot_catch<               Base *       volatile, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base *       volatile, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base *       volatile, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base *       volatile, Private *, Private>(); | 
|  | assert_cannot_catch<               Base * const volatile, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base * const volatile, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base * const volatile, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base * const volatile, Private *, Private>(); | 
|  | } | 
|  |  | 
|  | void f11() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //  cv1 Base * cv2 | 
|  | // cannot catch an exception of type: | 
|  | //  Protected * | 
|  | assert_cannot_catch<               Base *               , Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base *               , Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base *               , Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base *               , Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base * const         , Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base * const         , Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base * const         , Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base * const         , Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base *       volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base *       volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base *       volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base *       volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base * const volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base * const volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base * const volatile, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base * const volatile, Protected *, Protected>(); | 
|  | } | 
|  |  | 
|  | void f12() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //  cv1 Base * cv2 & | 
|  | // cannot catch an exception of type: | 
|  | //  Private * | 
|  | assert_cannot_catch<               Base *                &, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base *                &, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base *                &, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base *                &, Private *, Private>(); | 
|  | assert_cannot_catch<               Base * const          &, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base * const          &, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base * const          &, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base * const          &, Private *, Private>(); | 
|  | assert_cannot_catch<               Base *       volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base *       volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base *       volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base *       volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<               Base * const volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<const          Base * const volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<      volatile Base * const volatile &, Private *, Private>(); | 
|  | assert_cannot_catch<const volatile Base * const volatile &, Private *, Private>(); | 
|  | } | 
|  |  | 
|  | void f13() | 
|  | { | 
|  | // Test that every combination of handler of type: | 
|  | //  cv1 Base * cv2 & | 
|  | // cannot catch an exception of type: | 
|  | //  Protected * | 
|  | assert_cannot_catch<               Base *                &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base *                &, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base *                &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base *                &, Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base * const          &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base * const          &, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base * const          &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base * const          &, Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base *       volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base *       volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base *       volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base *       volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<               Base * const volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const          Base * const volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<      volatile Base * const volatile &, Protected *, Protected>(); | 
|  | assert_cannot_catch<const volatile Base * const volatile &, Protected *, Protected>(); | 
|  | } | 
|  |  | 
|  | int main(int, char**) | 
|  | { | 
|  | f1(); | 
|  | f2(); | 
|  | f3(); | 
|  | f4(); | 
|  | f5(); | 
|  | f6(); | 
|  | f7(); | 
|  | f8(); | 
|  | f9(); | 
|  | f10(); | 
|  | f11(); | 
|  | f12(); | 
|  | f13(); | 
|  |  | 
|  | return 0; | 
|  | } |