On 29/10/20 14:49 +0000, Jonathan Wakely wrote:
This change allows std::function::target<F>() 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<F*>(ptr). The standard only allows
const_cast<T*> when T is an object type.  The solution is to use
*const_cast<F**>(&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<void, void>):
        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.


commit 99bf3a817b9d31905dd12448e853ad2685635250
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Mon Nov 9 10:09:51 2020

    libstdc++: Include <typeinfo> even for -fno-rtti [PR 97758]
    
    The std::function code now uses std::type_info* even when RTTI is
    disabled, so it should include <typeinfo> unconditionally. Without this,
    Clang can't compile <functional> with -fno-rtti (it works with GCC
    because std::type_info gets declared automatically by the compiler).
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/97758
            * include/bits/std_function.h [!__cpp_rtti]: Include <typeinfo>.

diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h
index 054d9cbbf02b..1788b882a8aa 100644
--- a/libstdc++-v3/include/bits/std_function.h
+++ b/libstdc++-v3/include/bits/std_function.h
@@ -36,9 +36,7 @@
 # include <bits/c++0x_warning.h>
 #else
 
-#if __cpp_rtti
-# include <typeinfo>
-#endif
+#include <typeinfo>
 #include <bits/stl_function.h>
 #include <bits/invoke.h>
 #include <bits/refwrap.h>

Reply via email to