forked from OSchip/llvm-project
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 llvm-svn: 283408
This commit is contained in:
parent
5d0fbbbca1
commit
ae34c56ee7
|
@ -694,12 +694,6 @@ template <unsigned> struct __static_assert_check {};
|
||||||
#define _NOALIAS
|
#define _NOALIAS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define _LIBCPP_MAY_ALIAS __attribute__((__may_alias__))
|
|
||||||
#else
|
|
||||||
#define _LIBCPP_MAY_ALIAS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
|
#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
|
||||||
# define _LIBCPP_EXPLICIT explicit
|
# define _LIBCPP_EXPLICIT explicit
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -77,8 +77,6 @@ class _LIBCPP_EXCEPTION_ABI type_info
|
||||||
type_info& operator=(const type_info&);
|
type_info& operator=(const type_info&);
|
||||||
type_info(const type_info&);
|
type_info(const type_info&);
|
||||||
|
|
||||||
typedef size_t _LIBCPP_MAY_ALIAS _ASizeT; // Avoid strict-aliasing issues.
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||||
const char* __type_name;
|
const char* __type_name;
|
||||||
|
@ -119,7 +117,7 @@ public:
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
size_t hash_code() const _NOEXCEPT
|
size_t hash_code() const _NOEXCEPT
|
||||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||||
{return *reinterpret_cast<const _ASizeT *>(&__type_name);}
|
{return reinterpret_cast<size_t>(__type_name);}
|
||||||
#else
|
#else
|
||||||
{if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
|
{if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
|
||||||
const char *__ptr = name();
|
const char *__ptr = name();
|
||||||
|
|
Loading…
Reference in New Issue