libstdc++: Fix SFINAE with shared_ptr and invalid deleter
Ensures correct SFINAE behavior for shared_ptr constructors that accept deleters, aligning with C++20 constraints.
This change fixes SFINAE (Substitution Failure Is Not An Error) issues in libstdc++ concerning shared_ptr constructors that take a deleter. It implements the C++20 constraints for these constructors and proactively adopts a proposed resolution for LWG 4110, which relaxes constraints on nullptr_t overloads. New tests have been added to verify the corrected behavior.
In Details
The __shared_nullptr_ctor_tag and _ValidDeleter helper have been introduced in bits/shared_ptr.h and bits/shared_ptr_base.h respectively. These are used to constrain shared_ptr constructors and reset functions, ensuring that the deleter type meets specific requirements, particularly for nullptr_t overloads. This change addresses PR126120 and aligns with C++20's stricter SFINAE rules for smart pointers.
- SFINAE
- Substitution Failure Is Not An Error. A C++ language rule where an invalid substitution of template parameters is not treated as a hard error, allowing overload resolution to continue with other candidates. It's often used for compile-time introspection and enabling/disabling functionality based on type properties.
- shared_ptr
- A C++ smart pointer that manages a dynamically allocated object and provides shared ownership. It uses a reference count to determine when the object can be safely deallocated.
- deleter
- A function or function object passed to a smart pointer (like
shared_ptr) that is responsible for cleaning up the managed resource. This is an alternative to the defaultdeleteoperator. - LWG 4110
- A specific issue (number 4110) discussed and resolved by the C++ Library Working Group, concerning the constraints on
shared_ptrconstructors.