This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

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
	(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
	(__decay_selector<_Up, false, true>): Do not use add_pointer.
	* testsuite/20_util/bind/ New test.
	* testsuite/20_util/is_function/ New test.
	* testsuite/20_util/is_function/ Check more pointer types.
	* testsuite/20_util/is_member_function_pointer/ 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.

Attachment: patch.txt
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]