The _Arg_value::_M_set method, initialized the union member, by
assigning to reference to that member produced by _M_get(*this).
However, per language rules, such assignment has undefined behavior,
if alternative was not already active, same as for any object not
within its lifetime.
To address above, we modify _M_set to use placement new for the class
types, and invoke _S_access with two arguments for all other types.
The _S_access (rename of _S_get) is modified to assign the value of
the second parameter (if provided) to the union member. Such direct
assignments are treated specially in the language (see N5032
[class.union.general] p5), and will start lifetime of trivially default
constructible alternative.
libstdc++-v3/ChangeLog:
* include/std/format (_Arg_value::_M_get): Rename to...
(_Arg_value::_M_access): Modified to accept optional
second parameter that is assigned to value.
(_Arg_value::_M_get): Handle rename.
(_Arg_value::_M_set): Use construct_at for basic_string_view,
handle, and two-argument _S_access for other types.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Ivan Lazaric <ivan.lazaric1@gmail.com>
Co-authored-by: Ivan Lazaric <ivan.lazaric1@gmail.com>