libstdc++: Fix std::type_info::before for ARM [PR103240]

The r179236 fix for std::type_info::operator== should also have been
applied to std::type_info::before. Otherwise two distinct types can
compare equivalent due to using a string comparison, when they should do
a pointer comparison.

libstdc++-v3/ChangeLog:

	PR libstdc++/103240
	* libsupc++/tinfo2.cc (type_info::before): Use unadjusted name
	to check for the '*' prefix.
	* testsuite/util/testsuite_shared.cc: Add type_info object for
	use in new test.
	* testsuite/18_support/type_info/103240.cc: New test.
This commit is contained in:
Jonathan Wakely 2021-11-16 21:03:21 +00:00
parent c705464823
commit 054bf99841
3 changed files with 52 additions and 1 deletions

View File

@ -36,7 +36,10 @@ type_info::before (const type_info &arg) const _GLIBCXX_NOEXCEPT
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
return (name ()[0] == '*') ? name () < arg.name ()
/* The name() method will strip any leading '*' prefix. Therefore
take care to look at __name rather than name() when looking for
the "pointer" prefix. */
return (__name[0] == '*') ? name () < arg.name ()
: __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}

View File

@ -0,0 +1,36 @@
// { dg-do run }
// { dg-require-sharedlib "" }
// { dg-options "./testsuite_shared.so" }
#include <typeinfo>
#include <testsuite_hooks.h>
namespace __gnu_test
{
namespace
{
struct S { };
struct T { };
}
// Defined in testsuite_shared.so, referring to private type in that library
// with the same mangled name as __gnu_test::<anonymous>::S defined here.
extern const std::type_info& pr103240_private_S;
}
const std::type_info& private_S = __gnu_test::pr103240_private_S;
const std::type_info& local_S = typeid(__gnu_test::S);
const std::type_info& local_T = typeid(__gnu_test::T);
int main()
{
VERIFY( local_S == local_S );
VERIFY( ! local_S.before(local_S) );
VERIFY( local_S != local_T );
VERIFY( local_S.before(local_T) || local_T.before(local_S) );
VERIFY( local_S != private_S );
// PR libstdc++/103240
VERIFY( local_S.before(private_S) || private_S.before(local_S) );
}

View File

@ -23,6 +23,9 @@
#include <map>
#include <ext/mt_allocator.h>
#include <bits/functexcept.h>
#if __cpp_rtti
# include <typeinfo>
#endif
namespace __gnu_test
{
@ -130,4 +133,13 @@ try_function_random_fail()
}
#endif
#if __cpp_rtti
// PR libstdc++/103240
namespace
{
struct S { };
}
const std::type_info& pr103240_private_S = typeid(S);
#endif
} // end namepace __gnu_test