From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 146B43AA9825; Fri, 18 Jun 2021 14:43:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 146B43AA9825 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r9-9592] libstdc++: Do not use deduced return type for std::visit [PR 100384] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-9 X-Git-Oldrev: 79fa567e234585dc6a71f9bd069101c993513f3e X-Git-Newrev: 91d29ed563bd7e787921f997ea2f80cd87ee59b2 Message-Id: <20210618144340.146B43AA9825@sourceware.org> Date: Fri, 18 Jun 2021 14:43:40 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jun 2021 14:43:40 -0000 https://gcc.gnu.org/g:91d29ed563bd7e787921f997ea2f80cd87ee59b2 commit r9-9592-g91d29ed563bd7e787921f997ea2f80cd87ee59b2 Author: Jonathan Wakely Date: Tue May 4 12:16:46 2021 +0100 libstdc++: Do not use deduced return type for std::visit [PR 100384] This avoids errors outside the immediate context when std::visit is an overload candidate because of ADL, but not actually viable. The solution is to give std::visit a non-deduced return type. New helpers are introduced for that. libstdc++-v3/ChangeLog: PR libstdc++/100384 * include/std/variant (__get_t): New alias template yielding the return type of std::get on a variant. (__visit_result_t): New alias template yielding the result of std::visit. (__do_visit): Use __get_t. (visit): Use __visit_result_t for return type. * testsuite/20_util/variant/100384.cc: New test. (cherry picked from commit af5b2b911dd80ae9cc87404b7e7ab807cf6655d4) Diff: --- libstdc++-v3/include/std/variant | 19 ++++++++++++++----- libstdc++-v3/testsuite/20_util/variant/100384.cc | 9 +++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 321228753cd..99a35cc5915 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -1039,6 +1039,14 @@ namespace __variant std::index_sequence<__indices...>> : _Base_dedup<__indices, __poison_hash>>... { }; + template + using __get_t = decltype(std::get<_Np>(std::declval<_Variant>())); + + // Return type of std::visit. + template + using __visit_result_t + = invoke_result_t<_Visitor, __get_t<0, _Variants>...>; + } // namespace __variant } // namespace __detail @@ -1191,7 +1199,8 @@ namespace __variant #undef _VARIANT_RELATION_FUNCTION_TEMPLATE template - constexpr decltype(auto) visit(_Visitor&&, _Variants&&...); + constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> + visit(_Visitor&&, _Variants&&...); template inline enable_if_t<(is_move_constructible_v<_Types> && ...) @@ -1638,7 +1647,7 @@ namespace __variant __do_visit(_Visitor&& __visitor, _Variants&&... __variants) { using _Deduced_type = std::invoke_result<_Visitor, - decltype(std::get<0>(std::declval<_Variants>()))...>; + __detail::__variant::__get_t<0, _Variants>...>; using _Result_type = typename std::conditional_t<__use_index, __detail::__variant::__variant_idx_cookie, @@ -1654,14 +1663,14 @@ namespace __variant } template - constexpr decltype(auto) + constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) __throw_bad_variant_access("Unexpected index"); - return __do_visit(std::forward<_Visitor>(__visitor), - std::forward<_Variants>(__variants)...); + return std::__do_visit(std::forward<_Visitor>(__visitor), + std::forward<_Variants>(__variants)...); } #if __cplusplus > 201703L diff --git a/libstdc++-v3/testsuite/20_util/variant/100384.cc b/libstdc++-v3/testsuite/20_util/variant/100384.cc new file mode 100644 index 00000000000..4866aa017ff --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/variant/100384.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++17 } } + +#include + +int visit(int*, std::true_type) { return 0; } + +const std::true_type dat; + +int i = visit(nullptr, dat);