https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90246

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
It's too late to change this now, but we could still improve the messages:

--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1200,10 +1200,12 @@ namespace __variant
   {
   public:
     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
+
     const char* what() const noexcept override
     { return _M_reason; }

   private:
+    // Must only be called with a string literal
     bad_variant_access(const char* __reason) : _M_reason(__reason) { }

     const char* _M_reason;
@@ -1211,10 +1213,20 @@ namespace __variant
     friend void __throw_bad_variant_access(const char* __what);
   };

+  // Must only be called with a string literal
   inline void
   __throw_bad_variant_access(const char* __what)
   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }

+  inline void
+  __throw_bad_variant_access(bool __valueless)
+  {
+    if (__valueless) [[__unlikely__]]
+      __throw_bad_variant_access("std::get: variant is valueless");
+    else
+      __throw_bad_variant_access("std::get: wrong index for variant");
+  }
+
   template<typename... _Types>
     class variant
     : private __detail::__variant::_Variant_base<_Types...>,
@@ -1584,7 +1596,7 @@ namespace __variant
       static_assert(_Np < sizeof...(_Types),
                    "The index should be in [0, number of alternatives)");
       if (__v.index() != _Np)
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access(__v.valueless_by_exception());
       return __detail::__variant::__get<_Np>(__v);
     }

@@ -1595,7 +1607,7 @@ namespace __variant
       static_assert(_Np < sizeof...(_Types),
                    "The index should be in [0, number of alternatives)");
       if (__v.index() != _Np)
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access(__v.valueless_by_exception());
       return __detail::__variant::__get<_Np>(std::move(__v));
     }

@@ -1606,7 +1618,7 @@ namespace __variant
       static_assert(_Np < sizeof...(_Types),
                    "The index should be in [0, number of alternatives)");
       if (__v.index() != _Np)
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access(__v.valueless_by_exception());
       return __detail::__variant::__get<_Np>(__v);
     }

@@ -1617,7 +1629,7 @@ namespace __variant
       static_assert(_Np < sizeof...(_Types),
                    "The index should be in [0, number of alternatives)");
       if (__v.index() != _Np)
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access(__v.valueless_by_exception());
       return __detail::__variant::__get<_Np>(std::move(__v));
     }

@@ -1648,7 +1660,7 @@ namespace __variant
     visit(_Visitor&& __visitor, _Variants&&... __variants)
     {
       if ((__variants.valueless_by_exception() || ...))
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access("std::visit: variant is valueless");

       return __do_visit(std::forward<_Visitor>(__visitor),
                        std::forward<_Variants>(__variants)...);
@@ -1660,7 +1672,7 @@ namespace __variant
     visit(_Visitor&& __visitor, _Variants&&... __variants)
     {
       if ((__variants.valueless_by_exception() || ...))
-       __throw_bad_variant_access("Unexpected index");
+       __throw_bad_variant_access("std::visit<R>: variant is valueless");

       if constexpr (std::is_void_v<_Res>)
         (void) __do_visit<false, false>(std::forward<_Visitor>(__visitor),

Reply via email to