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