12f984cabSRichard Smith //===--------------------- catch_pointer_nullptr.cpp ----------------------===//
22f984cabSRichard Smith //
3*57b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*57b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*57b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62f984cabSRichard Smith //
72f984cabSRichard Smith //===----------------------------------------------------------------------===//
82f984cabSRichard Smith 
92f984cabSRichard Smith // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions
102f984cabSRichard Smith 
112f984cabSRichard Smith #include <cassert>
122f984cabSRichard Smith #include <cstdlib>
132f984cabSRichard Smith 
142f984cabSRichard Smith struct A {};
152f984cabSRichard Smith 
162f984cabSRichard Smith template<typename T, bool CanCatchNullptr>
172f984cabSRichard Smith static void catch_nullptr_test() {
182f984cabSRichard Smith   try {
192f984cabSRichard Smith     throw nullptr;
202f984cabSRichard Smith   } catch (T &p) {
2135c8983cSEric Fiselier     assert(CanCatchNullptr && !static_cast<bool>(p));
222f984cabSRichard Smith   } catch (...) {
232f984cabSRichard Smith     assert(!CanCatchNullptr);
242f984cabSRichard Smith   }
252f984cabSRichard Smith }
262f984cabSRichard Smith 
272f984cabSRichard Smith int main()
282f984cabSRichard Smith {
292f984cabSRichard Smith   using nullptr_t = decltype(nullptr);
302f984cabSRichard Smith 
312f984cabSRichard Smith   // A reference to nullptr_t can catch nullptr.
322f984cabSRichard Smith   catch_nullptr_test<nullptr_t, true>();
332f984cabSRichard Smith   catch_nullptr_test<const nullptr_t, true>();
342f984cabSRichard Smith   catch_nullptr_test<volatile nullptr_t, true>();
352f984cabSRichard Smith   catch_nullptr_test<const volatile nullptr_t, true>();
362f984cabSRichard Smith 
372f984cabSRichard Smith   // No other reference type can.
382f984cabSRichard Smith #if 0
392f984cabSRichard Smith   // FIXME: These tests fail, because the ABI provides no way for us to
402f984cabSRichard Smith   // distinguish this from catching by value.
412f984cabSRichard Smith   catch_nullptr_test<void *, false>();
422f984cabSRichard Smith   catch_nullptr_test<void * const, false>();
432f984cabSRichard Smith   catch_nullptr_test<int *, false>();
442f984cabSRichard Smith   catch_nullptr_test<A *, false>();
452f984cabSRichard Smith   catch_nullptr_test<int A::*, false>();
462f984cabSRichard Smith   catch_nullptr_test<int (A::*)(), false>();
472f984cabSRichard Smith #endif
482f984cabSRichard Smith }
49