From f30740348550dbeb32a6ac1ce450dfe46371b755 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Thu, 10 May 2018 20:59:35 +0000 Subject: [PATCH] Fix PR37407 - callable traits don't correctly check complete types. Checking for complete types is really rather tricky when you consider the amount of specializations required to check a function type. This specifically caused PR37407 where we incorrectly diagnosed noexcept function types as incomplete (but there were plenty of other cases that would cause this). This patch removes the complete type checking for now. I'm going to look into adding a clang builtin to correctly do this for us. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@332040 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/type_traits | 144 +----------------- .../meta.trans.other/result_of.pass.cpp | 24 ++- .../meta.trans.other/result_of11.pass.cpp | 14 ++ 3 files changed, 39 insertions(+), 143 deletions(-) diff --git a/include/type_traits b/include/type_traits index 5cb3b5c63..ec7739144 100644 --- a/include/type_traits +++ b/include/type_traits @@ -4168,147 +4168,6 @@ template struct __is_reference_wrapper #ifndef _LIBCPP_CXX03_LANG -// Check for complete types - -template struct __check_complete; - -template <> -struct __check_complete<> -{ -}; - -template -struct __check_complete<_Hp, _T0, _Tp...> - : private __check_complete<_Hp>, - private __check_complete<_T0, _Tp...> -{ -}; - -template -struct __check_complete<_Hp, _Hp> - : private __check_complete<_Hp> -{ -}; - -template -struct __check_complete<_Tp> -{ - static_assert(sizeof(_Tp) > 0, "Type must be complete."); -}; - -template -struct __check_complete<_Tp&> - : private __check_complete<_Tp> -{ -}; - -template -struct __check_complete<_Tp&&> - : private __check_complete<_Tp> -{ -}; - -template -struct __check_complete<_Rp (*)(_Param...)> - : private __check_complete<_Rp> -{ -}; - -template -struct __check_complete -{ -}; - -template -struct __check_complete<_Rp (_Param...)> - : private __check_complete<_Rp> -{ -}; - -template -struct __check_complete -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...)> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) &> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) &&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const&&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile&&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&> - : private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp _Class::*> - : private __check_complete<_Class> -{ -}; - - template ::type, class _DecayA0 = typename decay<_A0>::type, @@ -4491,8 +4350,9 @@ _LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...) template struct __invokable_r - : private __check_complete<_Fp> { + // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, + // or incomplete array types as required by the standard. using _Result = decltype( _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp index 24231526b..69e805d1e 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp @@ -104,36 +104,43 @@ int main() test_result_of (); } { // pointer to function - typedef bool (&RF0)(); + typedef bool (&RF0)(); typedef bool* (&RF1)(int); typedef bool& (&RF2)(int, int); typedef bool const& (&RF3)(int, int, int); + typedef bool (&RF4)(int, ...); typedef bool (*PF0)(); typedef bool* (*PF1)(int); typedef bool& (*PF2)(int, int); typedef bool const& (*PF3)(int, int, int); + typedef bool (*PF4)(int, ...); typedef bool (*&PRF0)(); typedef bool* (*&PRF1)(int); typedef bool& (*&PRF2)(int, int); typedef bool const& (*&PRF3)(int, int, int); + typedef bool (*&PRF4)(int, ...); test_result_of(); test_result_of(); test_result_of(); test_result_of(); + test_result_of(); test_result_of(); test_result_of(); test_result_of(); test_result_of(); + test_result_of(); test_result_of(); test_result_of(); test_result_of(); test_result_of(); + test_result_of(); } { // pointer to member function typedef int (S::*PMS0)(); typedef int* (S::*PMS1)(long); typedef int& (S::*PMS2)(long, int); + typedef const int& (S::*PMS3)(int, ...); test_result_of (); test_result_of (); test_result_of (); @@ -193,9 +200,13 @@ int main() test_no_result, int, int)>(); test_no_result, int, int)>(); + test_result_of(); + test_result_of(); + typedef int (S::*PMS0C)() const; typedef int* (S::*PMS1C)(long) const; typedef int& (S::*PMS2C)(long, int) const; + typedef const int& (S::*PMS3C)(int, ...) const; test_result_of (); test_result_of (); test_result_of (); @@ -238,9 +249,13 @@ int main() test_no_result(); test_no_result(); + test_result_of(); + test_result_of(); + typedef int (S::*PMS0V)() volatile; typedef int* (S::*PMS1V)(long) volatile; typedef int& (S::*PMS2V)(long, int) volatile; + typedef const int& (S::*PMS3V)(int, ...) volatile; test_result_of (); test_result_of (); test_result_of (); @@ -274,9 +289,13 @@ int main() test_no_result(); test_no_result(); + test_result_of(); + test_result_of(); + typedef int (S::*PMS0CV)() const volatile; typedef int* (S::*PMS1CV)(long) const volatile; typedef int& (S::*PMS2CV)(long, int) const volatile; + typedef const int& (S::*PMS3CV)(int, ...) const volatile; test_result_of (); test_result_of (); test_result_of (); @@ -321,6 +340,9 @@ int main() test_result_of (); test_result_of (); test_result_of, int, int), int&> (); + + test_result_of(); + test_result_of(); } { // pointer to member data typedef char S::*PMD; diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp index 2b8cd7096..f7fb7ccfd 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp @@ -58,6 +58,20 @@ void test_result_of_imp() int main() { + { // Function types with noexcept + typedef bool (&RF0)(int) noexcept; + typedef bool (&RF1)(int, ...) noexcept; + typedef bool (*PF0)(int) noexcept; + typedef bool (*PF1)(int, ...) noexcept; + typedef bool (*&PRF0)(int) noexcept; + typedef bool (*&PRF1)(int, ...) noexcept; + test_result_of_imp(); + test_result_of_imp(); + test_result_of_imp(); + test_result_of_imp(); + test_result_of_imp(); + test_result_of_imp(); + } { typedef char F::*PMD; test_result_of_imp();