From 72459cfd86389ead7ce0cdd09a3d272684105874 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 20 Aug 2019 22:21:15 +0100 Subject: [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, use a much simpler definition of std::is_function. Also redefine __is_referenceable to not rely on partial specializations for each type of referenceable function. PR libstdc++/91371 * include/std/type_traits (is_function): Simplify definition. Remove partial specializations for function types. (__is_referenceable): Simplify definition. * 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. * testsuite/20_util/is_object/91371.cc: New test. From-SVN: r274756 --- libstdc++-v3/ChangeLog | 12 ++ libstdc++-v3/include/std/type_traits | 130 +++--------------- libstdc++-v3/testsuite/20_util/bind/91371.cc | 37 +++++ .../testsuite/20_util/is_function/91371.cc | 47 +++++++ .../testsuite/20_util/is_function/value.cc | 6 + .../is_member_function_pointer/91371.cc | 35 +++++ .../testsuite/20_util/is_object/91371.cc | 38 +++++ 7 files changed, 195 insertions(+), 110 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/bind/91371.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_function/91371.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_member_function_pointer/91371.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_object/91371.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 086966a36d6..0717400f957 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2019-08-20 Jonathan Wakely + + PR libstdc++/91371 + * include/std/type_traits (is_function): Simplify definition. Remove + partial specializations for function types. + (__is_referenceable): Simplify definition. + * 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. + * testsuite/20_util/is_object/91371.cc: New test. + 2019-08-16 Uros Bizjak * config/abi/post/alpha-linux-gnu/baseline_symbols.txt: Update. diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 44db2cade5d..443208813b1 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -223,11 +223,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __failure_type { }; - // Primary type categories. - template struct remove_cv; + template + struct is_const; + + // Primary type categories. + template struct __is_void_helper : public false_type { }; @@ -481,105 +484,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /// is_function - template + template struct is_function - : public false_type { }; - - template - struct is_function<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; + : public __bool_constant::value> { }; - template - struct is_function<_Res(_ArgTypes......) const _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) const & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) const && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) volatile _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) volatile & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) volatile && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) volatile _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) volatile & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) volatile && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const volatile _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const volatile & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes...) const volatile && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) const volatile _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; - - template - struct is_function<_Res(_ArgTypes......) const volatile & _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; + template + struct is_function<_Tp&> + : public false_type { }; - template - struct is_function<_Res(_ArgTypes......) const volatile && _GLIBCXX_NOEXCEPT_QUAL> - : public true_type { }; + template + struct is_function<_Tp&&> + : public false_type { }; #define __cpp_lib_is_null_pointer 201309 @@ -706,20 +621,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >; + // __void_t (std::void_t for C++11) + template using __void_t = void; + // Utility to detect referenceable types ([defns.referenceable]). - template + template struct __is_referenceable - : public __or_, is_reference<_Tp>>::type - { }; - - template - struct __is_referenceable<_Res(_Args...) _GLIBCXX_NOEXCEPT_QUAL> - : public true_type + : public false_type { }; - template - struct __is_referenceable<_Res(_Args......) _GLIBCXX_NOEXCEPT_QUAL> + template + struct __is_referenceable<_Tp, __void_t<_Tp&>> : public true_type { }; @@ -2261,9 +2174,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct conditional { typedef _Iffalse type; }; - // __void_t (std::void_t for C++11) - template using __void_t = void; - /// common_type template struct common_type; diff --git a/libstdc++-v3/testsuite/20_util/bind/91371.cc b/libstdc++-v3/testsuite/20_util/bind/91371.cc new file mode 100644 index 00000000000..1c6f55e9ece --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/91371.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target c++11 } + +#include + +int bar(int) __attribute__((ms_abi)); +int baz(int) __attribute__((sysv_abi)); + +void +test01() +{ + // PR libstdc++/91371 + std::bind(bar, 5)(); + std::bind(baz, 5)(); + + static_assert(std::is_function::value, ""); + static_assert(std::is_function::value, ""); + static_assert(std::is_pointer>::value, ""); + static_assert(std::is_pointer>::value, ""); +} diff --git a/libstdc++-v3/testsuite/20_util/is_function/91371.cc b/libstdc++-v3/testsuite/20_util/is_function/91371.cc new file mode 100644 index 00000000000..c51d373027b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_function/91371.cc @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target c++11 } + +#include + +using std::is_function; + +#ifdef __i386__ +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +#endif +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); +static_assert(is_function::value, ""); + +struct X { operator X*(); }; +static_assert(!is_function::value, ""); +static_assert(!is_function::value, ""); +static_assert(!is_function::value, ""); +union Y { operator Y*(); int i; long l;}; +static_assert(!is_function::value, ""); +static_assert(!is_function::value, ""); +static_assert(!is_function::value, ""); diff --git a/libstdc++-v3/testsuite/20_util/is_function/value.cc b/libstdc++-v3/testsuite/20_util/is_function/value.cc index 7b94b58b6cb..4a3bb7c5740 100644 --- a/libstdc++-v3/testsuite/20_util/is_function/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_function/value.cc @@ -37,12 +37,18 @@ void test01() char (int, ClassType) const volatile &&>(true), ""); // Negative tests. + static_assert(test_category(false), ""); static_assert(test_category(false), ""); static_assert(test_category(false), ""); static_assert(test_category(false), ""); + static_assert(test_category(false), ""); + static_assert(test_category(false), ""); + static_assert(test_category(false), ""); + static_assert(test_category(false), ""); static_assert(test_category(false), ""); static_assert(test_category(false), ""); + static_assert(test_category(false), ""); // Sanity check. static_assert(test_category(false), ""); diff --git a/libstdc++-v3/testsuite/20_util/is_member_function_pointer/91371.cc b/libstdc++-v3/testsuite/20_util/is_member_function_pointer/91371.cc new file mode 100644 index 00000000000..25fecc11cd8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_member_function_pointer/91371.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target c++11 } + +#include + +struct Z +{ + void __attribute__((ms_abi)) f() const { } + void __attribute__((sysv_abi)) g() const { } +#ifdef __i386__ + void __attribute__((thiscall)) h() const { } +#endif +}; +static_assert( std::is_member_function_pointer::value, "" ); +static_assert( std::is_member_function_pointer::value, "" ); +#ifdef __i386__ +static_assert( std::is_member_function_pointer::value, "" ); +#endif diff --git a/libstdc++-v3/testsuite/20_util/is_object/91371.cc b/libstdc++-v3/testsuite/20_util/is_object/91371.cc new file mode 100644 index 00000000000..3520d7680d2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_object/91371.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target c++11 } + +#include + +using std::is_object; + +#ifdef __i386__ +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +#endif +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); +static_assert(!is_object::value, ""); -- 2.30.2