-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lifetime cleanups for basic_string
#4047
Lifetime cleanups for basic_string
#4047
Conversation
auto& _Al = _Getal(); | ||
_Destroy_in_place(_My_data._Bx._Ptr); | ||
_My_data._Activate_SSO_buffer(); | ||
_Deallocate_for_capacity(_Al, _Ptr, _My_data._Myres); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly irrelevant; it also seems that these assignments in this function(_Tidy_deallocate
) are actually useless, as _Tidy_deallocate
seems always to be followed by methods that just rewrite these values. (based on current codebase; as like "remaining issue" part in the description, I'm uncertain about ABI impact of this change :(
_My_data._Mysize = 0;
_My_data._Myres = _Small_string_capacity;
// the _Traits::assign is last so the codegen doesn't think the char write can alias this
_Traits::assign(_My_data._Bx._Buf[0], _Elem());
@@ -946,6 +946,20 @@ _CONSTEXPR20 void test_string_swap(const size_t id1, const size_t id2) { | |||
assert(dst.get_allocator().id() == id1); | |||
} | |||
|
|||
#if _HAS_CXX20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't have to be guarded by _HAS_CXX20
, as strbuf(move(str))
will still call copy constructor in pre-cpp20 mode. However, I think adding _HAS_CXX20
will make it more obvious that the leak is relevant to basic_stringbuf(basic_string&&,...)
introduced in C++20.
…nit` in constructors.
…ate_SSO_buffer`, introduce `_Switch_to_buf`.
3e8ab56
to
25ec337
Compare
This comment was marked as resolved.
This comment was marked as resolved.
Thanks for these fine-grained commits, they made reviewing very straightforward! After thinking about each one, I believe that this PR has no ABI impact, and we should proceed as-is since it fixes the lifetime bug and generally makes it harder to introduce such mistakes in the future. Each commit is a transformation that doesn't introduce new inter-function assumptions (as far as I can tell). This PR is definitely complicated enough and changing a highly-used, risky area of the codebase that we'll need a second maintainer signoff. It definitely seems like any followup PR to remove |
This comment was marked as resolved.
This comment was marked as resolved.
1 similar comment
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
1 similar comment
This comment was marked as resolved.
This comment was marked as resolved.
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
Thanks for making |
Resolves the comments (1) (2) in pr 4031. Hope that is the last lifetime bug of
basic_string
using fancy pointers (3.1.
).Sometimes the pointer's destruction and buffer's activation are dangerously separated into different functions, in an obscure way (mainly relevant to the usage of
_Tidy_init
).This pr introduces a helper function
_String_val::_Bxty::_Switch_to_buf
to make the transition state (where both_Ptr
and_Buf
are inactive) invisible tobasic_string
's ctors and methods.Remaining issue after this pr:
STL/stl/inc/xstring
Lines 2282 to 2284 in 48eedd3
As
_String_val
already initializes the buffer on construction, and every switch back to small mode is now protected by the helper function, inbasic_string
's ctor and methods, when we can decide a string is in small mode, we can also assume that elements in_Buf
are activated. Therefore, every remaining usage of_Activate_SSO_buffer
(including the one in newly added_Construct_empty
) becomes redundant...Or,
Don't rely on the new behavior
? Does this mean we should not assume that_Buf
is initialized in ctor, even if it does so now? Can we remove the remaining_Activate_SSO_buffer
then? I'm highly horrified by this; especially, what's its relation with the lifetime issue of fancy pointers?Related: #1735 #3235 and #3273.