]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: fix uses of explicit object parameter [PR116038]
authorPatrick Palka <ppalka@redhat.com>
Thu, 25 Jul 2024 13:02:13 +0000 (09:02 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 25 Jul 2024 13:02:13 +0000 (09:02 -0400)
commit1066a95aa33eee2d2bd9c8324f34dedb967f338c
tree2fc22ae52a110142a06e9a0748bb2d0c8e974d5a
parentd6849aa926665cbee8bf87822401ca44f881753f
libstdc++: fix uses of explicit object parameter [PR116038]

The type of an implicit object parameter is always the current class.
For an explicit object parameter however, its deduced type can be a
derived class of the current class.  So when combining multiple
implicit-object overloads into a single explicit-object overload we need
to account for this possibility.  For example when accessing a member of
the current class through an explicit object parameter, it may now be a
derived class from which the member is not accessible, as in the below
testcases.

This pitfall is discussed[1] in the deducing this paper.  The general
solution is to cast the explicit object parameter to (a reference to)
the current class rather than e.g. using std::forward which preserves
the deduced type.

This patch corrects the existing problematic uses of explicit object
parameters in the library, all of which forward the parameter via
std::forward, to instead cast the parameter to the current class via
our __like_t alias template.  Note that unlike the paper's like_t,
ours always returns a reference so we can just write

  __like_t<Self, B>(self)

instead of

  (_like_t<Self, B>&&)self

as the paper does.

[1]: https://wg21.link/P0847#name-lookup-within-member-functions (and the
section after that)

PR libstdc++/116038

libstdc++-v3/ChangeLog:

* include/std/functional (_Bind_front::operator()): Use __like_t
instead of std::forward when forwarding __self.
(_Bind_back::operator()): Likewise.
* include/std/ranges (_Partial::operator()): Likewise.
(_Pipe::operator()): Likewise.
* testsuite/20_util/function_objects/bind_back/116038.cc: New test.
* testsuite/20_util/function_objects/bind_front/116038.cc: New test.
* testsuite/std/ranges/adaptors/116038.cc: New test.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/include/std/functional
libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/20_util/function_objects/bind_back/116038.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/function_objects/bind_front/116038.cc [new file with mode: 0644]
libstdc++-v3/testsuite/std/ranges/adaptors/116038.cc [new file with mode: 0644]