1*2f984cabSRichard Smith //===--------------------- catch_pointer_nullptr.cpp ----------------------===// 2*2f984cabSRichard Smith // 3*2f984cabSRichard Smith // The LLVM Compiler Infrastructure 4*2f984cabSRichard Smith // 5*2f984cabSRichard Smith // This file is dual licensed under the MIT and the University of Illinois Open 6*2f984cabSRichard Smith // Source Licenses. See LICENSE.TXT for details. 7*2f984cabSRichard Smith // 8*2f984cabSRichard Smith //===----------------------------------------------------------------------===// 9*2f984cabSRichard Smith 10*2f984cabSRichard Smith // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions 11*2f984cabSRichard Smith 12*2f984cabSRichard Smith #include <cassert> 13*2f984cabSRichard Smith #include <cstdlib> 14*2f984cabSRichard Smith 15*2f984cabSRichard Smith struct A {}; 16*2f984cabSRichard Smith 17*2f984cabSRichard Smith template<typename T, bool CanCatchNullptr> 18*2f984cabSRichard Smith static void catch_nullptr_test() { 19*2f984cabSRichard Smith try { 20*2f984cabSRichard Smith throw nullptr; 21*2f984cabSRichard Smith } catch (T &p) { 22*2f984cabSRichard Smith assert(CanCatchNullptr && !p); 23*2f984cabSRichard Smith } catch (...) { 24*2f984cabSRichard Smith assert(!CanCatchNullptr); 25*2f984cabSRichard Smith } 26*2f984cabSRichard Smith } 27*2f984cabSRichard Smith 28*2f984cabSRichard Smith int main() 29*2f984cabSRichard Smith { 30*2f984cabSRichard Smith using nullptr_t = decltype(nullptr); 31*2f984cabSRichard Smith 32*2f984cabSRichard Smith // A reference to nullptr_t can catch nullptr. 33*2f984cabSRichard Smith catch_nullptr_test<nullptr_t, true>(); 34*2f984cabSRichard Smith catch_nullptr_test<const nullptr_t, true>(); 35*2f984cabSRichard Smith catch_nullptr_test<volatile nullptr_t, true>(); 36*2f984cabSRichard Smith catch_nullptr_test<const volatile nullptr_t, true>(); 37*2f984cabSRichard Smith 38*2f984cabSRichard Smith // No other reference type can. 39*2f984cabSRichard Smith #if 0 40*2f984cabSRichard Smith // FIXME: These tests fail, because the ABI provides no way for us to 41*2f984cabSRichard Smith // distinguish this from catching by value. 42*2f984cabSRichard Smith catch_nullptr_test<void *, false>(); 43*2f984cabSRichard Smith catch_nullptr_test<void * const, false>(); 44*2f984cabSRichard Smith catch_nullptr_test<int *, false>(); 45*2f984cabSRichard Smith catch_nullptr_test<A *, false>(); 46*2f984cabSRichard Smith catch_nullptr_test<int A::*, false>(); 47*2f984cabSRichard Smith catch_nullptr_test<int (A::*)(), false>(); 48*2f984cabSRichard Smith #endif 49*2f984cabSRichard Smith } 50