-
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
fixing std::shared_ptr<void> initialization from void* #3873
Conversation
class `shared_ptr` is optimized to avoid keeping a deleter object for non-primitive types which are detected using `_Can_scalar_delete`. This class relies on SFINAE to detect if the operator delete is valid for a given pointer type. It turns out that delete a void* is valid in msvc, though, according to the standard is undefined behaviour (7.6.2.9). By specializing for void is possible to prevent direct initialization of `shared_ptr<void>` from a void* and prevent bugs. Note that `default_deleter<void>` is not valid too.
Is this a compiler bug? #include <memory>
constexpr int foo() {
void* p = new int;
delete p;
return 0;
}
int main() { constexpr auto f = foo(); }
|
@achabense , no. We have |
Hmm... _Can_scalar_delete |
It seems that the standard wording in [expr.delete] is defective. In the core spec, "shall" generally means that requirements for well-formedness, not for the well-definedness of the behavior. However, "shall" sometimes introduces UB in [expr.delete], and it's not clear whether deleting a
|
FYI, I'm calling this "bug" rather than "enhancement" since [util.smartptr.shared.const]/4 says we should be diagnosing this as ill-formed. |
Sticking to metaprogramming available in C++14
avoid using resolution for std namespace types
This comment was marked as resolved.
This comment was marked as resolved.
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 fixing this bug and congratulations on your first microsoft/STL commit! 🚀 🎉 🥳 |
class
shared_ptr
is optimized to avoid keeping a deleter object for non-primitive types which are detected using_Can_scalar_delete
. This class relies on SFINAE to detect if the operator delete is valid for a given pointer type. It turns out that delete a void* is valid in msvc, though, according to the standard is undefined behaviour (7.6.2.9). By specializing for void is possible to prevent direct initialization ofshared_ptr<void>
from a void* and prevent bugs. Note thatdefault_deleter<void>
is not valid too.