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