diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-06-04 20:38:23 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-06-04 20:38:23 +0000 |
| commit | f52318b47b333126c862d9a973d6e59ccaf713dc (patch) | |
| tree | 7859cdba92b95d143927b8a5b11466c1cfc071f3 /libcxx/include/__hash_table | |
| parent | ba81d7f1ebfd30bf354390f8656211041d53c176 (diff) | |
| download | bcm5719-llvm-f52318b47b333126c862d9a973d6e59ccaf713dc.tar.gz bcm5719-llvm-f52318b47b333126c862d9a973d6e59ccaf713dc.zip | |
Fix a strict aliasing violation in map and unordered_map.
These containers type-punned between pair<K, V> and pair<const K, V> as an
optimization. This commit instead provides access to the pair via a pair of
references that assign through to the underlying object. It's still undefined to
mutate a const object, but clang doesn't optimize on this for data members, so
this should be safe.
Differential revision: https://reviews.llvm.org/D47607
llvm-svn: 333948
Diffstat (limited to 'libcxx/include/__hash_table')
| -rw-r--r-- | libcxx/include/__hash_table | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 3f430af1283..44ba268a0ec 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -32,13 +32,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Tp> -union __hash_value_type; -#else template <class _Key, class _Tp> struct __hash_value_type; -#endif template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> @@ -172,7 +167,7 @@ struct __hash_key_value_types { } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __container_value_type&& __move(__node_value_type& __v) { + static __container_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v); } #endif @@ -184,7 +179,6 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { typedef _Tp mapped_type; typedef __hash_value_type<_Key, _Tp> __node_value_type; typedef pair<const _Key, _Tp> __container_value_type; - typedef pair<_Key, _Tp> __nc_value_type; typedef __container_value_type __map_value_type; static const bool __is_map = true; @@ -198,7 +192,7 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&>::type __get_value(_Up& __t) { - return __t.__cc; + return __t.__get_value(); } template <class _Up> @@ -211,12 +205,12 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { _LIBCPP_INLINE_VISIBILITY static __container_value_type* __get_ptr(__node_value_type& __n) { - return _VSTD::addressof(__n.__cc); + return _VSTD::addressof(__n.__get_value()); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __nc_value_type&& __move(__node_value_type& __v) { - return _VSTD::move(__v.__nc); + static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { + return __v.__move(); } #endif |

