Fix strict-aliasing violation in typeinfo::hash_code()

Summary:
The current implementation of `hash_code()` for uniqued RTTI strings violates strict aliasing by dereferencing a type-punned pointer. Specifically it generates a `const char**` pointer from the address of the `__name` member before casting it to `const size_t*` and dereferencing it to get the hash. This is really just a complex and incorrect way of writing `reinterpret_cast<size_t>(__name)`.

This patch changes the conversion sequence so that it no longer contains UB.


Reviewers: howard.hinnant, mclow.lists

Subscribers: rjmccall, cfe-commits

Differential Revision: https://reviews.llvm.org/D24012

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@283408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier 2016-10-05 22:55:10 +00:00
parent f5293bc6ac
commit 1d6b5d3ed1
2 changed files with 1 additions and 9 deletions

View File

@ -694,12 +694,6 @@ template <unsigned> struct __static_assert_check {};
#define _NOALIAS
#endif
#ifdef __GNUC__
#define _LIBCPP_MAY_ALIAS __attribute__((__may_alias__))
#else
#define _LIBCPP_MAY_ALIAS
#endif
#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
# define _LIBCPP_EXPLICIT explicit
#else

View File

@ -77,8 +77,6 @@ class _LIBCPP_EXCEPTION_ABI type_info
type_info& operator=(const type_info&);
type_info(const type_info&);
typedef size_t _LIBCPP_MAY_ALIAS _ASizeT; // Avoid strict-aliasing issues.
protected:
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
const char* __type_name;
@ -119,7 +117,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
size_t hash_code() const _NOEXCEPT
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
{return *reinterpret_cast<const _ASizeT *>(&__type_name);}
{return reinterpret_cast<size_t>(__type_name);}
#else
{if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
const char *__ptr = name();