Repository navigation
fix(smart_holder): keep void-cast semantics in from_unique_ptr - #6163
Merged
rwgk merged 5 commits intoOct 5, 2026
Merged
Conversation
Collaborator
|
@henryiii I'm looking at this now. I'll merge master before I do my full review. |
…t-holder-unique-ptr-shared-from-this
rwgk
approved these changes
Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 AI text below 🤖
smart_holder::from_unique_ptr()always built the owningshared_ptrfrom aT *. This connects thestd::enable_shared_from_thismachinery to the holder control block. For trampoline (alias) types,shared_from_this()must not access this control block, because the resultingshared_ptrdoes not keep the Python object alive.The
void_cast_raw_ptrflag indetail/init.hwas made ineffective by #5836, which changed the second parameter offrom_unique_ptr()into a multiple-inheritance subobject pointer. As a result, a factory that returns aunique_ptrto a trampoline lost the guard, and the Python override could disappear silently.from_unique_ptr()now has an explicitvoid_cast_raw_ptrparameter. When it is true, the raw pointer is cast tovoid *before constructing the owningshared_ptr. Ashared_ptr<void>constructed from aT *would still connect theenable_shared_from_thismachinery to its control block; converting an existingshared_ptr<T>toshared_ptr<void>is also too late. The multiple-inheritance behavior does not change.This restores the ownership safeguard introduced in #3023. The holder's internal control block cannot retain the Python trampoline without creating a reference cycle that Python's garbage collector cannot detect.
shared_from_this()initially throwsbad_weak_ptr, but remains available once C++ holds a separateshared_ptrthat retains the Python trampoline.Fixes item 4 of #6159.
Suggested changelog entry:
py::init()factories returning astd::unique_ptrto a trampoline incorrectly exposing the holder's control block toshared_from_this().