Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1446,18 +1446,86 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (*__p)(_Ap..., ...)) { return __p; } template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile) {return __p;} + +#if __has_feature(cxx_reference_qualified_functions) + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) volatile &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile &) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile &) {return __p;} + + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) volatile &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile &&) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile &&) {return __p;} +#endif // __has_feature(cxx_reference_qualified_functions) + template _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;} Index: test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp =================================================================== --- test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp +++ test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp @@ -11,7 +11,7 @@ // class function -// function(nullptr_t); +// function(Fp); #include #include Index: test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// class function + +// function(Fp); + +// Ensure that __not_null works for all function types. +// See https://llvm.org/bugs/show_bug.cgi?id=23589 + +#include +#include + +struct A {}; + +#define NULL_CV_TYPE + +#define TEST_CV_TYPE(CV) \ + test(); \ + test(); \ + test(); \ + test(); \ + test(); \ + test() + +template +void test() { + MemFn mf = nullptr; + std::function f = mf; + A a; + try { f(static_cast(a)); assert(false); } + catch (std::bad_function_call&) {} +} + +int main() { + { + void (*p)() = nullptr; + std::function< void() > f = p; + try { f(); } + catch ( std::bad_function_call & ) {} + } + { + void (*p)(...) = nullptr; + std::function< void() > f = p; + try { f(); } + catch ( std::bad_function_call & ) {} + } + { + TEST_CV_TYPE( NULL_CV_TYPE ); + TEST_CV_TYPE( const ); + TEST_CV_TYPE( volatile ); + TEST_CV_TYPE( const volatile ); + } +} \ No newline at end of file