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