Fix a possible crash when unreferencing an empty CowData<T> #87233
+8
−8
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.
Fixes #87076.
CowData<T>::_unref()
was implemented like this:On the surface,
if (!p_data)
doesn't do anything becauseMemory::free_static()
uses its own null check and the parameter is otherwise unused, so in the release builds of Godot 4.2.1 and 4.3 dev 1 (and most likely others), there is at least one occasion where this check is optimized out by the compiler. However, the method assumes thatp_data == this->_ptr
, so thatif (!p_data)
is an implicit check forif (this->_ptr != nullptr)
. If the compiler, unaware of this assumption, removes theif (!p_data)
, thenif (refc->decrement() > 0)
dereferences a null pointer wheneverthis->_ptr
is null.The
p_data
parameter makes it possible to decrement the reference count of the internal pointer but then free a different pointer should that reference count reach zero. I'm not sure what the original use case for this was, especially since the method may crash should you pass in anything other thanthis->ptr
. In the current code, the method is only ever called as_unref(_ptr)
.I removed the
p_data
parameter and made the method explicitly operate onthis->_ptr
. This should prevent the compiler from optimizing the check out although I don't know how to create an official release build, so I can't check the generated code.Since
CowData<T>
is the internal data structure used inString
andVector<T>
, this change affects basically the whole engine. Hopefully in a good way.