From b39f6a79ee88ea0c626a467ade032f052c9ce139 Mon Sep 17 00:00:00 2001 From: Fehr Mathieu Date: Mon, 13 Sep 2021 18:15:13 +0000 Subject: [PATCH] [ADT] Extend EnableIfCallable for callables with incomplete returns std::is_convertible has no defined behavior when its arguments are incomplete, even if they are equal. In practice, it returns false. Adding std::is_same allows us to use the constructor using a callable, even if the return value is incomplete. We also check the case where we convert a T into a const T. Reviewed By: DaniilSuchkov Differential Revision: https://reviews.llvm.org/D104703 Committer: Daniil Suchkov --- llvm/include/llvm/ADT/FunctionExtras.h | 15 ++++++++++----- llvm/unittests/ADT/FunctionExtrasTest.cpp | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h index e67ef73..43e98de 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h @@ -64,11 +64,16 @@ template using EnableUnlessSameType = std::enable_if_t, ThisT>::value>; template -using EnableIfCallable = - std::enable_if_t::value || - std::is_convertible()( - std::declval()...)), - Ret>::value>; +using EnableIfCallable = std::enable_if_t, + std::is_same()(std::declval()...)), + Ret>, + std::is_same()( + std::declval()...)), + Ret>, + std::is_convertible()( + std::declval()...)), + Ret>>::value>; template class UniqueFunctionBase { protected: diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp index 3c6f179..fc856a9 100644 --- a/llvm/unittests/ADT/FunctionExtrasTest.cpp +++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp @@ -291,4 +291,23 @@ TEST(UniqueFunctionTest, IncompleteTypes) { unique_function *()> IncompleteResultPointer; } +// Incomplete function returning an incomplete type +Incomplete incompleteFunction(); +const Incomplete incompleteFunctionConst(); + +// Check that we can assign a callable to a unique_function when the +// callable return value is incomplete. +TEST(UniqueFunctionTest, IncompleteCallableType) { + unique_function IncompleteReturnInCallable{incompleteFunction}; + unique_function IncompleteReturnInCallableConst{ + incompleteFunctionConst}; + unique_function IncompleteReturnInCallableConstConversion{ + incompleteFunction}; +} + +// Define the incomplete function +class Incomplete {}; +Incomplete incompleteFunction() { return {}; } +const Incomplete incompleteFunctionConst() { return {}; } + } // anonymous namespace -- 2.7.4