/ test / catch_reference_nullptr.pass.cpp
catch_reference_nullptr.pass.cpp
 1  //===--------------------- catch_pointer_nullptr.cpp ----------------------===//
 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-exception
 6  //
 7  //===----------------------------------------------------------------------===//
 8  
 9  // UNSUPPORTED: c++03,
10  // UNSUPPORTED: no-exceptions
11  
12  #include <cassert>
13  #include <cstdlib>
14  
15  struct A {};
16  
17  template<typename T, bool CanCatchNullptr>
18  static void catch_nullptr_test() {
19    try {
20      throw nullptr;
21    } catch (T &p) {
22      assert(CanCatchNullptr && !static_cast<bool>(p));
23    } catch (...) {
24      assert(!CanCatchNullptr);
25    }
26  }
27  
28  int main(int, char**)
29  {
30    using nullptr_t = decltype(nullptr);
31  
32    // A reference to nullptr_t can catch nullptr.
33    catch_nullptr_test<nullptr_t, true>();
34    catch_nullptr_test<const nullptr_t, true>();
35    catch_nullptr_test<volatile nullptr_t, true>();
36    catch_nullptr_test<const volatile nullptr_t, true>();
37  
38    // No other reference type can.
39  #if 0
40    // FIXME: These tests fail, because the ABI provides no way for us to
41    // distinguish this from catching by value.
42    catch_nullptr_test<void *, false>();
43    catch_nullptr_test<void * const, false>();
44    catch_nullptr_test<int *, false>();
45    catch_nullptr_test<A *, false>();
46    catch_nullptr_test<int A::*, false>();
47    catch_nullptr_test<int (A::*)(), false>();
48  #endif
49  
50    return 0;
51  }