On 29/10/20 14:49 +0000, Jonathan Wakely wrote: >This change allows std::function::target() to work even without RTTI, >using the same approach as std::any. Because we know what the manager >function would be for a given type, we can check if the stored pointer >has the expected address. If it does, we don't need to use RTTI. If it >isn't equal, we still need to do the RTTI check (when RTTI is enabled) >to handle the case where the same function has different addresses in >different shared objects. > >This also changes the implementation of the manager function to return a >null pointer result when asked for the type_info of the target object. >This not only avoids a warning with -Wswitch -Wsystem-headers, but also >avoids prevents std::function::target_type() from dereferencing an >uninitialized pointer when the linker keeps an instantiation of the >manager function that was compiled without RTTI. > >Finally, this fixes a bug in the non-const overload of function::target >where calling it with a function type F was ill-formed, due to >attempting to use const_cast(ptr). The standard only allows >const_cast when T is an object type. The solution is to use >*const_cast(&ptr) instead, because F* is an object type even if F >isn't. I've also used _GLIBCXX17_CONSTEXPR in function::target so that >it doesn't bother instantiating anything for types that can never be a >valid target. > >libstdc++-v3/ChangeLog: > > * include/bits/std_function.h (_Function_handler): > Define explicit specialization used for invalid target types. > (_Base_manager::_M_manager) [!__cpp_rtti]: Return null. > (function::target_type()): Check for null pointer. > (function::target()): Define unconditionall. Fix bug with > const_cast of function pointer type. > (function::target() const): Define unconditionally, but > only use RTTI if enabled. > * testsuite/20_util/function/target_no_rtti.cc: New test. This fixes a problem with that previous patch. Tested x86_64-linux. Committed to trunk.