libstdc++: Fix visitor return type diagnostics [PR97449]
authorVille Voutilainen <ville.voutilainen@gmail.com>
Sat, 17 Oct 2020 19:08:50 +0000 (22:08 +0300)
committerVille Voutilainen <ville.voutilainen@gmail.com>
Sat, 17 Oct 2020 20:10:40 +0000 (23:10 +0300)
libstdc++-v3/ChangeLog:

PR libstdc++/97449
* include/std/variant
(__gen_vtable_impl<>::_S_apply_single_alt):
Diagnose visitor return type mismatches here..
(__gen_vtable_impl</*base case*/>::_S_apply):
..not here.

libstdc++-v3/include/std/variant

index a29c5bf513bf3f3ccc5a194c3799defc914279f5..17f8bcd638b80926f609cfae2149c7e6d202f0fb 100644 (file)
@@ -960,9 +960,13 @@ namespace __variant
            }
          else
            {
-             __element = __gen_vtable_impl<
+             auto __tmp_element = __gen_vtable_impl<
                remove_reference_t<decltype(__element)>,
                std::index_sequence<__indices..., __index>>::_S_apply();
+             static_assert(is_same_v<_Tp, decltype(__tmp_element)>,
+                           "std::visit requires the visitor to have the same "
+                           "return type for all alternatives of a variant");
+             __element = __tmp_element;
            }
        }
     };
@@ -1026,10 +1030,8 @@ namespace __variant
                                    std::declval<_Variants>()...))>;
            if constexpr (__visit_ret_type_mismatch)
              {
-               static_assert(!__visit_ret_type_mismatch,
-                 "std::visit requires the visitor to have the same "
-                 "return type for all alternatives of a variant");
-               return __nonesuch{};
+               struct __cannot_match {};
+               return __cannot_match{};
              }
            else
              return _Array_type{&__visit_invoke};