public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org
Subject: [gcc r11-8363] libstdc++: Do not use deduced return type for std::visit [PR 100384]
Date: Thu,  6 May 2021 13:06:10 +0000 (GMT)	[thread overview]
Message-ID: <20210506130610.3F7203A4E86C@sourceware.org> (raw)

https://gcc.gnu.org/g:e99763ee6da8e378073b847243d9ac2538903534

commit r11-8363-ge99763ee6da8e378073b847243d9ac2538903534
Author: Jonathan Wakely <jwakely@redhat.com>
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, and existing ones refactored slightly.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/100384
            * include/std/variant (__get_t): New alias template yielding the
            return type of std::get<N> on a variant.
            (__visit_result_t): New alias template yielding the result of
            std::visit.
            (__same_types): Move into namespace __detail::__variant.
            (__check_visitor_results): Likewise. Use __invoke_result_t and
            __get_t.
            (__check_visitor_result): Remove.
            (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                 | 50 ++++++++++++------------
 libstdc++-v3/testsuite/20_util/variant/100384.cc |  9 +++++
 2 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 1ef9b9725e2..9b2bc440841 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1063,6 +1063,25 @@ namespace __variant
 			      std::index_sequence<__indices...>>
     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
 
+  template<size_t _Np, typename _Variant>
+    using __get_t = decltype(std::get<_Np>(std::declval<_Variant>()));
+
+  // Return type of std::visit.
+  template<typename _Visitor, typename... _Variants>
+    using __visit_result_t
+      = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
+
+  template<typename _Tp, typename... _Types>
+    constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
+
+  template <typename _Visitor, typename _Variant, size_t... _Idxs>
+    constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
+    {
+      return __same_types<
+	invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
+	>;
+    }
+
 } // namespace __variant
 } // namespace __detail
 
@@ -1248,7 +1267,8 @@ namespace __variant
 #endif
 
   template<typename _Visitor, typename... _Variants>
-    constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
+    constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
+    visit(_Visitor&&, _Variants&&...);
 
   template<typename... _Types>
     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
@@ -1715,41 +1735,21 @@ namespace __variant
 			   std::forward<_Variants>(__variants)...);
     }
 
-  template<typename _Tp, typename... _Types>
-     constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
-
-  template <size_t _Idx, typename _Visitor, typename _Variant>
-    decltype(auto)
-    __check_visitor_result(_Visitor&& __vis, _Variant&& __variant)
-    {
-      return std::__invoke(std::forward<_Visitor>(__vis),
-			   std::get<_Idx>(std::forward<_Variant>(__variant)));
-    }
-
-  template <typename _Visitor, typename _Variant, size_t... _Idxs>
-    constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
-    {
-      return __same_types<decltype(__check_visitor_result<_Idxs>(
-	std::declval<_Visitor>(),
-	std::declval<_Variant>()))...>;
-    }
-
-
   template<typename _Visitor, typename... _Variants>
-    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("std::visit: variant is valueless");
 
-      using _Result_type = std::invoke_result_t<_Visitor,
-	decltype(std::get<0>(std::declval<_Variants>()))...>;
+      using _Result_type
+	= __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
 
       using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
 
       if constexpr (sizeof...(_Variants) == 1)
 	{
-	  constexpr bool __visit_rettypes_match =
+	  constexpr bool __visit_rettypes_match = __detail::__variant::
 	    __check_visitor_results<_Visitor, _Variants...>(
 	      std::make_index_sequence<
 	        std::variant_size<remove_reference_t<_Variants>...>::value>());
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 <variant>
+
+int visit(int*, std::true_type) { return 0; }
+
+const std::true_type dat;
+
+int i = visit(nullptr, dat);


                 reply	other threads:[~2021-05-06 13:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210506130610.3F7203A4E86C@sourceware.org \
    --to=redi@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    --cc=libstdc++-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).