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