1 //===--------------------- catch_pointer_nullptr.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 // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions
11 
12 #include <cassert>
13 #include <cstdlib>
14 
15 // Clang emits a warning on converting an object of type nullptr_t to bool,
16 // even in generic code. Suppress it.
17 #if defined(__clang__)
18 #pragma clang diagnostic ignored "-Wnull-conversion"
19 #endif
20 
21 struct A {};
22 
23 template<typename T, bool CanCatchNullptr>
24 static void catch_nullptr_test() {
25   try {
26     throw nullptr;
27   } catch (T &p) {
28     assert(CanCatchNullptr && !p);
29   } catch (...) {
30     assert(!CanCatchNullptr);
31   }
32 }
33 
34 int main()
35 {
36   using nullptr_t = decltype(nullptr);
37 
38   // A reference to nullptr_t can catch nullptr.
39   catch_nullptr_test<nullptr_t, true>();
40   catch_nullptr_test<const nullptr_t, true>();
41   catch_nullptr_test<volatile nullptr_t, true>();
42   catch_nullptr_test<const volatile nullptr_t, true>();
43 
44   // No other reference type can.
45 #if 0
46   // FIXME: These tests fail, because the ABI provides no way for us to
47   // distinguish this from catching by value.
48   catch_nullptr_test<void *, false>();
49   catch_nullptr_test<void * const, false>();
50   catch_nullptr_test<int *, false>();
51   catch_nullptr_test<A *, false>();
52   catch_nullptr_test<int A::*, false>();
53   catch_nullptr_test<int (A::*)(), false>();
54 #endif
55 }
56