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