]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Pass small trivial types by value in polymorphic wrappers
authorTomasz Kamiński <tkaminsk@redhat.com>
Wed, 28 May 2025 09:16:22 +0000 (11:16 +0200)
committerTomasz Kamiński <tkaminsk@redhat.com>
Mon, 2 Jun 2025 11:52:35 +0000 (13:52 +0200)
commit08031b88e2a32cc334af540703c5332a6b716529
tree0a58c44995b78d11c7d494088d56898f0d9a4904
parenta2e1c97205063d7550d9b9c32319715961abd73f
libstdc++: Pass small trivial types by value in polymorphic wrappers

This patch adjust the passing of parameters for the move_only_function,
copyable_function and function_ref. For types that are declared as being passed
by value in signature template argument, they are passed by value to the invoker,
when they are small (at most two pointers), trivially move constructible and
trivially destructible. The latter guarantees that passing them by value has not
user visible side effects.

In particular, this extends the set of types forwarded by value, that was
previously limited to scalars, to also include specializations of std::span and
std::string_view, and similar standard and program defined-types.

Checking the suitability of the parameter types requires the types to be complete.
As a consequence, the implementation imposes requirements on instantiation of
move_only_function and copyable_function. To avoid producing the errors from
the implementation details, a static assertion was added to partial
specializations of copyable_function, move_only_function and function_ref.
The static assertion uses existing __is_complete_or_unbounded, as arrays type
parameters are automatically decayed in function type.

Standard already specifies in [res.on.functions] p2.5 that instantiating these
partial specialization with incomplete types leads to undefined behavior.

libstdc++-v3/ChangeLog:

* include/bits/funcwrap.h (__polyfunc::__pass_by_rref): Define.
(__polyfunc::__param_t): Update to use __pass_by_rref.
* include/bits/cpyfunc_impl.h:: Assert that are parameters type
are complete.
* include/bits/funcref_impl.h: Likewise.
* include/bits/mofunc_impl.h: Likewise.
* testsuite/20_util/copyable_function/call.cc: New test.
* testsuite/20_util/function_ref/call.cc: New test.
* testsuite/20_util/move_only_function/call.cc: New test.
* testsuite/20_util/copyable_function/conv.cc: New test.
* testsuite/20_util/function_ref/conv.cc: New test.
* testsuite/20_util/move_only_function/conv.cc: New test.
* testsuite/20_util/copyable_function/incomplete_neg.cc: New test.
* testsuite/20_util/function_ref/incomplete_neg.cc: New test.
* testsuite/20_util/move_only_function/incomplete_neg.cc: New test.

Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
13 files changed:
libstdc++-v3/include/bits/cpyfunc_impl.h
libstdc++-v3/include/bits/funcref_impl.h
libstdc++-v3/include/bits/funcwrap.h
libstdc++-v3/include/bits/mofunc_impl.h
libstdc++-v3/testsuite/20_util/copyable_function/call.cc
libstdc++-v3/testsuite/20_util/copyable_function/conv.cc
libstdc++-v3/testsuite/20_util/copyable_function/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/function_ref/call.cc
libstdc++-v3/testsuite/20_util/function_ref/conv.cc
libstdc++-v3/testsuite/20_util/function_ref/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/move_only_function/call.cc
libstdc++-v3/testsuite/20_util/move_only_function/conv.cc
libstdc++-v3/testsuite/20_util/move_only_function/incomplete_neg.cc [new file with mode: 0644]