[PATCH] PR libstdc++/91371 make std::is_function handle other calling conventions

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] PR libstdc++/91371 make std::is_function handle other calling conventions

Jonathan Wakely-3
The x86 attributes such as ms_abi, stdcall, fastcall etc. alter the
function type, which means that functions with one of those attributes
do not match any of the partial specializations of std::is_function.

Rather than duplicating the list for every calling convention, this
adds a fallback to the std::is_function primary template which
identifies other function types. The fallback works by assuming that
all function types fall into one of two categories: referenceable and
abominable. The former can be detected by testing for
function-to-pointer decay, and the latter are non-referenceable types
that are not cv void.

In order to detect referenceable types it's necessary to replace the
current definition of __is_referenceable with one that doesn't depend on
std::is_function, to avoid a cycle. The definition of std::decay can
also be modified to only act on referenceable function types, because
abominable function types do not decay.

        PR libstdc++/91371
        * include/std/type_traits (__declval, declval, __void_t): Declare
        earlier in the file.
        (__is_referenceable): Rewrite to not depend on is_function.
        (__is_referenceable_function): New trait to identify non-abominable
        function types.
        (__is_qualified_function): New alias to identify abominable function
        types.
        (is_function): Make primary template use __is_referenceable_function
        and __is_qualified_function to detect function types not covered by
        the partial specializations.
        (__decay_selector): Use __is_referenceable_function instead of
        is_function.
        (__decay_selector<_Up, false, true>): Do not use add_pointer.
        * testsuite/20_util/bind/91371.cc: New test.
        * testsuite/20_util/is_function/91371.cc: New test.
        * testsuite/20_util/is_function/value.cc: Check more pointer types.
        * testsuite/20_util/is_member_function_pointer/91371.cc: New test.

Tested x86_64-linux. Not committed yet.

I'd like to hear Daniel's thoughts on this approach, as he wrote the
original __is_referenceable trait, and much of <type_traits>.

This new __is_referenceable simply uses void_t<T&> to detect whether
forming T& is valid.

The detection for function-to-pointer decay works by checking whether
static_cast<T*>(declval<T&>()) is well-formed. If T is not a class
type (which could have a conversion operator) and is not nullptr or cv
void*cv (which can convert to nullptr* and cv void*cv* repectively)
then it must be a function.

The detection for abominable function types assumes that all types are
referenceable except functions with cv- or ref-qualifiers and cv void
types. So if it's not referenceable and not void, it's an abominable
function type.



patch.txt (13K) Download Attachment