1*eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
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
931cbe0f2SLouis 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>
catch_nullptr_test()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
main(int,char **)28504bc07dSLouis Dionne int main(int, char**)
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
49504bc07dSLouis Dionne
50504bc07dSLouis Dionne return 0;
512f984cabSRichard Smith }
52