diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2024-10-02 18:14:34 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-09-11 14:56:28 +0200 |
commit | b2b2ac34ba48bf22534574c0ac1abed09328f473 (patch) | |
tree | 34339fc2d601cf7bafcca7fd84462bb8b8801474 /libgcc/config/bfin | |
parent | 0b0ffa44c1881a52e5c624d369a090403919e61a (diff) | |
download | gcc-master.zip gcc-master.tar.gz gcc-master.tar.bz2 |
Converting a weak_ptr<Derived> to a weak_ptr<Base> requires calling
lock() on the source object in the general case.
Although the source weak_ptr<Derived> does contain a raw pointer to
Derived, we can't just get it and (up)cast it to Base, as that will
dereference the pointer in case Base is a virtual base class of Derived.
We don't know if the managed object is still alive, and therefore if
this operation is safe to do; we therefore temporarily lock() the source
weak_ptr, do the cast using the resulting shared_ptr, and then discard
this shared_ptr. Simply checking the strong counter isn't sufficient,
because if multiple threads are involved then we'd have a race / TOCTOU
problem; the object may get destroyed after we check the strong counter
and before we cast the pointer.
However lock() is not necessary if we know that Base is *not* a virtual
base class of Derived; in this case we can avoid the relatively
expensive call to lock() and just cast the pointer. This commit uses
the newly added builtin to detect this case and optimize std::weak_ptr's
converting constructors and assignment operations.
Apart from non-virtual bases, there's also another couple of interesting
cases where we can also avoid locking. Specifically:
1) converting a weak_ptr<T[N]> to a weak_ptr<T cv[]>;
2) converting a weak_ptr<T*> to a weak_ptr<T const * const> or similar.
Since this logic is going to be used by multiple places, I've
centralized it in a new static helper.
libstdc++-v3/ChangeLog:
* include/bits/shared_ptr_base.h (__weak_ptr): Avoid calling
lock() when converting or assigning a weak_ptr<Derived> to
a weak_ptr<Base> in case Base is not a virtual base of Derived.
This logic is centralized in _S_safe_upcast, called by the
various converting constructors/assignment operators.
(_S_safe_upcast): New helper function.
* testsuite/20_util/weak_ptr/cons/virtual_bases.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'libgcc/config/bfin')
0 files changed, 0 insertions, 0 deletions