1eb8650a7SLouis 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
9*29253332SRyan Prichard // UNSUPPORTED: c++03
108c61114cSLouis Dionne // UNSUPPORTED: no-exceptions
112f984cabSRichard Smith
122f984cabSRichard Smith #include <cassert>
13*29253332SRyan Prichard #include <cstddef>
142f984cabSRichard Smith #include <cstdlib>
15*29253332SRyan Prichard #include <type_traits>
162f984cabSRichard Smith
172f984cabSRichard Smith struct A {};
182f984cabSRichard Smith
192f984cabSRichard Smith template<typename T, bool CanCatchNullptr>
catch_nullptr_test()202f984cabSRichard Smith static void catch_nullptr_test() {
212f984cabSRichard Smith try {
222f984cabSRichard Smith throw nullptr;
232f984cabSRichard Smith } catch (T &p) {
2435c8983cSEric Fiselier assert(CanCatchNullptr && !static_cast<bool>(p));
252f984cabSRichard Smith } catch (...) {
262f984cabSRichard Smith assert(!CanCatchNullptr);
272f984cabSRichard Smith }
282f984cabSRichard Smith }
292f984cabSRichard Smith
main(int,char **)30504bc07dSLouis Dionne int main(int, char**)
312f984cabSRichard Smith {
32*29253332SRyan Prichard static_assert(std::is_same<std::nullptr_t, decltype(nullptr)>::value, "");
332f984cabSRichard Smith
342f984cabSRichard Smith // A reference to nullptr_t can catch nullptr.
35*29253332SRyan Prichard catch_nullptr_test<std::nullptr_t, true>();
36*29253332SRyan Prichard catch_nullptr_test<const std::nullptr_t, true>();
37*29253332SRyan Prichard catch_nullptr_test<volatile std::nullptr_t, true>();
38*29253332SRyan Prichard catch_nullptr_test<const volatile std::nullptr_t, true>();
392f984cabSRichard Smith
402f984cabSRichard Smith // No other reference type can.
412f984cabSRichard Smith #if 0
422f984cabSRichard Smith // FIXME: These tests fail, because the ABI provides no way for us to
432f984cabSRichard Smith // distinguish this from catching by value.
442f984cabSRichard Smith catch_nullptr_test<void *, false>();
452f984cabSRichard Smith catch_nullptr_test<void * const, false>();
462f984cabSRichard Smith catch_nullptr_test<int *, false>();
472f984cabSRichard Smith catch_nullptr_test<A *, false>();
482f984cabSRichard Smith catch_nullptr_test<int A::*, false>();
492f984cabSRichard Smith catch_nullptr_test<int (A::*)(), false>();
502f984cabSRichard Smith #endif
51504bc07dSLouis Dionne
52504bc07dSLouis Dionne return 0;
532f984cabSRichard Smith }
54