forked from OSchip/llvm-project
__invokable and __invoke_of now check for incomplete types and issue a compile-time diagnostic if they are used with incomplete types for anything except a return type. Note that both arguments *and* parameters are checked for completeness.
llvm-svn: 131818
This commit is contained in:
parent
a8805fd71a
commit
5eb6bdfa1d
|
@ -3586,10 +3586,10 @@ private:
|
|||
public:
|
||||
weak_ptr();
|
||||
template<class _Yp> weak_ptr(shared_ptr<_Yp> const& __r,
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat());
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0);
|
||||
weak_ptr(weak_ptr const& __r);
|
||||
template<class _Yp> weak_ptr(weak_ptr<_Yp> const& __r,
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat());
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0);
|
||||
|
||||
~weak_ptr();
|
||||
|
||||
|
@ -3640,7 +3640,7 @@ template<class _Tp>
|
|||
template<class _Yp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
|
@ -3652,7 +3652,7 @@ template<class _Tp>
|
|||
template<class _Yp>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
|
||||
typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
|
|
|
@ -845,7 +845,15 @@ struct __type_list
|
|||
typedef _Tp _Tail;
|
||||
};
|
||||
|
||||
struct __nat {};
|
||||
struct __nat
|
||||
{
|
||||
#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
|
||||
__nat() = delete;
|
||||
__nat(const __nat&) = delete;
|
||||
__nat& operator=(const __nat&) = delete;
|
||||
~__nat() = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __align_type
|
||||
|
@ -2775,6 +2783,140 @@ template <class _Tp> struct _LIBCPP_VISIBLE is_trivial
|
|||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
// Check for complete types
|
||||
|
||||
template <class ..._T> struct __check_complete;
|
||||
|
||||
template <>
|
||||
struct __check_complete<>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _H, class _T0, class ..._T>
|
||||
struct __check_complete<_H, _T0, _T...>
|
||||
: private __check_complete<_H>,
|
||||
private __check_complete<_T0, _T...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _H>
|
||||
struct __check_complete<_H, _H>
|
||||
: private __check_complete<_H>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _T>
|
||||
struct __check_complete<_T>
|
||||
{
|
||||
static_assert(sizeof(_T) > 0, "Type must be complete.");
|
||||
};
|
||||
|
||||
template <class _T>
|
||||
struct __check_complete<_T&>
|
||||
: private __check_complete<_T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _T>
|
||||
struct __check_complete<_T&&>
|
||||
: private __check_complete<_T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class ..._Param>
|
||||
struct __check_complete<_R (*)(_Param...)>
|
||||
: private __check_complete<_Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class ..._Param>
|
||||
struct __check_complete<_R (_Param...)>
|
||||
: private __check_complete<_Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...)>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) volatile>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const volatile>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
#if __has_feature(cxx_reference_qualified_functions)
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) &>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) volatile&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const volatile&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) &&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const&&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) volatile&&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
template <class _R, class _Class, class ..._Param>
|
||||
struct __check_complete<_R (_Class::*)(_Param...) const volatile&&>
|
||||
: private __check_complete<_Class, _Param...>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class _R, class _Class>
|
||||
struct __check_complete<_R _Class::*>
|
||||
: private __check_complete<_Class>
|
||||
{
|
||||
};
|
||||
|
||||
// __invoke forward declarations
|
||||
|
||||
// fall back - none of the bullets
|
||||
|
@ -2819,6 +2961,7 @@ __invoke(_F&& __f, _Args&& ...__args)
|
|||
|
||||
template <class _F, class ..._Args>
|
||||
struct __invokable_imp
|
||||
: private __check_complete<_F, _Args...>
|
||||
{
|
||||
typedef decltype(
|
||||
__invoke(_STD::declval<_F>(), _STD::declval<_Args>()...)
|
||||
|
|
Loading…
Reference in New Issue