1*2f984cabSRichard Smith //===--------------------- catch_pointer_nullptr.cpp ----------------------===//
2*2f984cabSRichard Smith //
3*2f984cabSRichard Smith //                     The LLVM Compiler Infrastructure
4*2f984cabSRichard Smith //
5*2f984cabSRichard Smith // This file is dual licensed under the MIT and the University of Illinois Open
6*2f984cabSRichard Smith // Source Licenses. See LICENSE.TXT for details.
7*2f984cabSRichard Smith //
8*2f984cabSRichard Smith //===----------------------------------------------------------------------===//
9*2f984cabSRichard Smith 
10*2f984cabSRichard Smith // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions
11*2f984cabSRichard Smith 
12*2f984cabSRichard Smith #include <cassert>
13*2f984cabSRichard Smith #include <cstdlib>
14*2f984cabSRichard Smith 
15*2f984cabSRichard Smith struct A {};
16*2f984cabSRichard Smith 
17*2f984cabSRichard Smith template<typename T, bool CanCatchNullptr>
18*2f984cabSRichard Smith static void catch_nullptr_test() {
19*2f984cabSRichard Smith   try {
20*2f984cabSRichard Smith     throw nullptr;
21*2f984cabSRichard Smith   } catch (T &p) {
22*2f984cabSRichard Smith     assert(CanCatchNullptr && !p);
23*2f984cabSRichard Smith   } catch (...) {
24*2f984cabSRichard Smith     assert(!CanCatchNullptr);
25*2f984cabSRichard Smith   }
26*2f984cabSRichard Smith }
27*2f984cabSRichard Smith 
28*2f984cabSRichard Smith int main()
29*2f984cabSRichard Smith {
30*2f984cabSRichard Smith   using nullptr_t = decltype(nullptr);
31*2f984cabSRichard Smith 
32*2f984cabSRichard Smith   // A reference to nullptr_t can catch nullptr.
33*2f984cabSRichard Smith   catch_nullptr_test<nullptr_t, true>();
34*2f984cabSRichard Smith   catch_nullptr_test<const nullptr_t, true>();
35*2f984cabSRichard Smith   catch_nullptr_test<volatile nullptr_t, true>();
36*2f984cabSRichard Smith   catch_nullptr_test<const volatile nullptr_t, true>();
37*2f984cabSRichard Smith 
38*2f984cabSRichard Smith   // No other reference type can.
39*2f984cabSRichard Smith #if 0
40*2f984cabSRichard Smith   // FIXME: These tests fail, because the ABI provides no way for us to
41*2f984cabSRichard Smith   // distinguish this from catching by value.
42*2f984cabSRichard Smith   catch_nullptr_test<void *, false>();
43*2f984cabSRichard Smith   catch_nullptr_test<void * const, false>();
44*2f984cabSRichard Smith   catch_nullptr_test<int *, false>();
45*2f984cabSRichard Smith   catch_nullptr_test<A *, false>();
46*2f984cabSRichard Smith   catch_nullptr_test<int A::*, false>();
47*2f984cabSRichard Smith   catch_nullptr_test<int (A::*)(), false>();
48*2f984cabSRichard Smith #endif
49*2f984cabSRichard Smith }
50