libstdc++: Gracefully handle unrecognized _Arg_t values in basic_format_arg.

Implementing features from later revision of the standard, may require
extending the set of types stored directly in _Arg_value (without
changing in size and aliment), and thus expanding the values in _Arg_t.
However, any such value would be unrecognized by the TUs compiled with
older release, and would lead to UB (call to __builtin_unreachable).

This patch addresses above by introducing _M_handle_unrecognized method,
that is called instead. As specializations of this method for all
context supported at runtime (format_context and wformat_context) are
exported from libstdc++.so, the newest version (supporting all _Arg_t
values introduced later) will be picked (this is ensured by not providing
template definition in header in such case).
In consequence, the implementation may return handle object referencing
new alternatives (such wrapping is already required to provide standard
compliant behavior of visit_format_arg).
As no new _Arg_t were introduced since GCC16, this method simply throws
format_error now, and contains appropriate comment.

Note that the above is not required for formatting when __do_vformat_to
is exported (Unicode literal encoding and C++20). It remains necessary
in remaining cases or when visit on basic_format_arg is called by user.
In consequence addition of new argument types stored directly does not
have negative impact on performance in most common case.

This patch also removes the __type parameter from the _M_visit and
_M_visit_user, and uses _M_type member instead. This prevents misuse,
as the provided type was always required to match _M_type.

libstdc++-v3/ChangeLog:

	* config/abi/pre/gnu.ver (GLIBCXX_3.4.36): Export basic_format_arg
	_M_handle_unrecognized method of specializations of
	format_context and wformat_context.
	* include/std/format (basic_format_arg::_M_handle_unrecognized):
	Declare with explicit specializations for (w)format_context
	if _GLIBCXX_EXTERN_TEMPLATE, and define otherwise.
	(basic_format_arg::_M_visit): Remove __type parameter, and use
	_M_type instead. Call _M_handle_unrecognized for unrecognized
	_Arg_t values.
	(basic_format_arg::_M_visit_user): Remove __type parameter,
	and use _M_type instead. Adjust calls to _M_visit.
	(basic_format_arg::visit, std::visit_format_arg)
	(__format::__visit_format_arg): Remove _M_type argument from
	_M_visit(_user) calls.
	* src/c++20/format-inst.cc
	(basic_format_arg::_M_handle_unrecognized): Define and export
	explicit specializations for (w)format_context.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
3 files changed