Bug 22552 – moveEmplace wipes context pointer of nested struct contained in non-nested struct

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-11-29T19:07:19Z
Last change time
2022-01-06T09:23:14Z
Keywords
pull
Assigned to
No Owner
Creator
Stanislav Blinov

Comments

Comment #0 by stanislav.blinov — 2021-11-29T19:07:19Z
import core.lifetime; void main() { int i; struct Nested { ~this() { ++i; } } static struct NotNested { Nested n; } auto a = NotNested(Nested()); // when this is destructed things go boom... NotNested b = void; moveEmplace(a, b); // ...because this wipes context pointer in a.n } // segmentation fault --- That's because moveEmplace simply blits NotNested.init into a. Instead it probably should move things fieldwise and avoid wiping context pointers in fields that are nested structs.
Comment #1 by kinke — 2021-11-29T20:27:52Z
(In reply to Stanislav Blinov from comment #0) > That's because moveEmplace simply blits NotNested.init into a. Instead it > probably should move things fieldwise and avoid wiping context pointers in > fields that are nested structs. Blitting the whole thing at once is still fine, but the problem arises with the T.init reset of the source instance. It would probably really have to reset the fields recursively in order not to clear any context pointers. There should IMO still be a fast path for the very common case of no nested context pointers.
Comment #2 by stanislav.blinov — 2021-11-30T09:17:36Z
Yes, bulk bit copy into destination would be fine, it's initializer blit that causes a problem. Although, if we're going to recursively inspect structs and static arrays to find any nested struct members, might as well make that recursion also emit the blits. Also, I have another enhancement in mind that could require recursive reflection: IMO, moving anything that has a pointer should require wiping the source (except for context pointers). I'll file that separately. Also, there's the question of const fields... Bleh. I'll make the pull for this issue later today, and we can discuss the details there.
Comment #3 by dlang-bot — 2021-11-30T18:43:56Z
@radcapricorn created dlang/druntime pull request #3638 "Fix Issue 22552 - moveEmplace wipes context pointer of nested struct …" fixing this issue: - Fix Issue 22552 - moveEmplace wipes context pointer of nested struct contained in non-nested struct https://github.com/dlang/druntime/pull/3638
Comment #4 by dlang-bot — 2022-01-06T09:23:14Z
dlang/druntime pull request #3638 "Fix Issue 22552 - moveEmplace wipes context pointer of nested struct …" was merged into master: - 6fee027668fb8905e9c22cb5532dfc1fd4f6c478 by Stanislav Blinov: Fix Issue 22552 - moveEmplace wipes context pointer of nested struct contained in non-nested struct https://github.com/dlang/druntime/pull/3638