aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/18_support
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2022-01-05 14:25:37 +0000
committerJonathan Wakely <jwakely@redhat.com>2022-01-05 14:43:01 +0000
commit3633cc54284450433b81f0340483e15df1a49a3c (patch)
tree8999cf5da81331352168bc23b5c930a1e90822d0 /libstdc++-v3/testsuite/18_support
parent096228d84e9238d97fe115623126373f5b67bdc1 (diff)
downloadgcc-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.cc48
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() );