diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2022-01-05 14:25:37 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2022-01-05 14:43:01 +0000 |
commit | 3633cc54284450433b81f0340483e15df1a49a3c (patch) | |
tree | 8999cf5da81331352168bc23b5c930a1e90822d0 /libstdc++-v3/testsuite/18_support | |
parent | 096228d84e9238d97fe115623126373f5b67bdc1 (diff) | |
download | gcc-3633cc54284450433b81f0340483e15df1a49a3c.zip gcc-3633cc54284450433b81f0340483e15df1a49a3c.tar.gz gcc-3633cc54284450433b81f0340483e15df1a49a3c.tar.bz2 |
libstdc++: Implement P1328 "Making std::type_info::operator== constexpr"
This feature is present in the C++23 draft.
With Jakub's recent front-end changes we can implement constexpr
equality by comparing the addresses of std::type_info objects. We do not
need string comparisons, because for constant evaluation cases we know
we aren't dealing with std::type_info objects defined in other
translation units.
The ARM EABI requires that the type_info::operator== function can be
defined out-of-line (and suggests that should be the default), but to be
a constexpr function it must be defined inline (at least for C++23
mode). To meet these conflicting requirements we make the inline version
of operator== call a new __equal function when called at runtime. That
is an alias for the non-inline definition of operator== defined in
libsupc++.
libstdc++-v3/ChangeLog:
* config/abi/pre/gnu.ver (GLIBCXX_3.4.30): Export new symbol for
ARM EABI.
* include/bits/c++config (_GLIBCXX23_CONSTEXPR): Define.
* include/std/version (__cpp_lib_constexpr_typeinfo): Define.
* libsupc++/tinfo.cc: Add #error to ensure non-inline definition
is emitted.
(type_info::__equal): Define alias symbol.
* libsupc++/typeinfo (type_info::before): Combine different
implementations into one.
(type_info::operator==): Likewise. Use address equality for
constant evaluation. Call __equal for targets that require the
definition to be non-inline.
* testsuite/18_support/type_info/constexpr.cc: New test.
Diffstat (limited to 'libstdc++-v3/testsuite/18_support')
-rw-r--r-- | libstdc++-v3/testsuite/18_support/type_info/constexpr.cc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/18_support/type_info/constexpr.cc b/libstdc++-v3/testsuite/18_support/type_info/constexpr.cc new file mode 100644 index 0000000..07f4fb6 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/type_info/constexpr.cc @@ -0,0 +1,48 @@ +// { dg-options "-std=gnu++23 -frtti" } +// { dg-do compile { target c++23 } } + +#include <typeinfo> + +#ifndef __cpp_lib_constexpr_typeinfo +# error "Feature-test macro for constexpr typeinfo missing in <typeinfo>" +#elif __cpp_lib_constexpr_typeinfo != 202106L +# error "Feature-test macro for constexpr typeinfo has wrong value in <typeinfo>" +#endif + +struct X { }; + +constexpr bool +test01() +{ + if (typeid(int) == typeid(long)) + return false; + + if (typeid(int) != typeid(int)) + return false; + + struct X { virtual ~X() { } }; + + if (typeid(X) != typeid(X)) + return false; + + if (typeid(X) == typeid(::X)) + return false; + + if (typeid(X) == typeid(int)) + return false; + + const auto& ti_x = typeid(X); + if (ti_x != ti_x) + return false; + + if (ti_x != typeid(X)) + return false; + + struct Y { }; + if (ti_x == typeid(Y)) + return false; + + return true; +} + +static_assert( test01() ); |