[PATCH] PR libstdc++/87431 re-adjust never-valueless optimizations

Jonathan Wakely jwakely@redhat.com
Fri Apr 5 16:59:00 GMT 2019


On 03/04/19 17:25 +0100, Jonathan Wakely wrote:
>Avoid creating arbitrarily large objects on the stack when creating
>temporaries in order to provide the strong exception-safety guarantee.
>
>Also implement Antony Polukhin's suggestion to whitelist specific types
>that can be efficiently move-assigned, so that emplacing those types
>never causes a variant to become valueless. The whitelisted types are:
>all trivially copyable types no greater than 256 bytes in size,
>std::shared_ptr, std::weak_ptr, std::unique_ptr, std::function, and
>std::any. Additionally, std::basic_string, std::vector, and
>__gnu_debug::vector are whitelisted if their allocator traits give them
>a non-throwing move assignment operator. Specifically, this means
>std::string is whitelisted, but std::pmr::string is not.
>
>	PR libstdc++/87431 (again)
>	* include/bits/basic_string.h (__variant::_Never_valueless_alt):
>	Define partial specialization for basic_string.
>	* include/bits/shared_ptr.h (_Never_valueless_alt): Likewise for
>	shared_ptr and weak_ptr.
>	* include/bits/std_function.h (_Never_valueless_alt): Likewise for
>	function.
>	* include/bits/stl_vector.h (_Never_valueless_alt): Likewise for
>	vector.
>	* include/bits/unique_ptr.h (_Never_valueless_alt): Likewise for
>	unique_ptr.
>	* include/debug/vector (_Never_valueless_alt): Likewise for debug
>	vector.
>	* include/std/any (_Never_valueless_alt): Define explicit
>	specialization for any.
>	* include/std/variant (_Never_valueless_alt): Define primary template.
>	(__never_valueless): Use _Never_valueless_alt instead of
>	is_trivially_copyable.
>	(variant::emplace<N>(Args&&...)): Add special case for non-throwing
>	initializations to avoid try-catch overhead. Add special case for
>	scalars produced by potentially-throwing conversions. Use
>	_Never_valueless_alt instead of is_trivially_copyable for the
>	remaining strong exception-safety cases.
>	(variant::emplace<N>(initializer_list<U>, Args&&...)): Likewise.
>	* testsuite/20_util/variant/87431.cc: Run both test functions.
>	* testsuite/20_util/variant/exception_safety.cc: New test.
>	* testsuite/20_util/variant/run.cc: Use pmr::string instead of string,
>	so the variant becomes valueless.
>
>I'd like to commit this to trunk this week. Does anybody see any
>problems with this approach?

I've committed this patch.

We can still consider whitelisting other types until the GCC 9
release, but we should do it soon.



More information about the Libstdc++ mailing list