12f984cabSRichard Smith //===--------------------- catch_pointer_nullptr.cpp ----------------------===// 22f984cabSRichard Smith // 32f984cabSRichard Smith // The LLVM Compiler Infrastructure 42f984cabSRichard Smith // 52f984cabSRichard Smith // This file is dual licensed under the MIT and the University of Illinois Open 62f984cabSRichard Smith // Source Licenses. See LICENSE.TXT for details. 72f984cabSRichard Smith // 82f984cabSRichard Smith //===----------------------------------------------------------------------===// 92f984cabSRichard Smith 102f984cabSRichard Smith // UNSUPPORTED: c++98, c++03, libcxxabi-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) { 22*35c8983cSEric 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