EricWF created this revision.
EricWF added reviewers: mclow.lists, howard.hinnant.
EricWF added a subscriber: cfe-commits.

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.


https://reviews.llvm.org/D24012

Files:
  include/__config
  include/typeinfo

Index: include/typeinfo
===================================================================
--- include/typeinfo
+++ include/typeinfo
@@ -74,8 +74,6 @@
     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;
@@ -116,7 +114,7 @@
     _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();
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -691,12 +691,6 @@
 #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


Index: include/typeinfo
===================================================================
--- include/typeinfo
+++ include/typeinfo
@@ -74,8 +74,6 @@
     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;
@@ -116,7 +114,7 @@
     _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();
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -691,12 +691,6 @@
 #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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to