public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r9-9592] libstdc++: Do not use deduced return type for std::visit [PR 100384]
@ 2021-06-18 14:43 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-06-18 14:43 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:91d29ed563bd7e787921f997ea2f80cd87ee59b2

commit r9-9592-g91d29ed563bd7e787921f997ea2f80cd87ee59b2
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.
    
    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.
            (__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<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>...>;
+
 } // namespace __variant
 } // namespace __detail
 
@@ -1191,7 +1199,8 @@ namespace __variant
 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
 
   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> && ...)
@@ -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<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("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 <variant>
+
+int visit(int*, std::true_type) { return 0; }
+
+const std::true_type dat;
+
+int i = visit(nullptr, dat);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-18 14:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-18 14:43 [gcc r9-9592] libstdc++: Do not use deduced return type for std::visit [PR 100384] Jonathan Wakely

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).