summaryrefslogtreecommitdiffstats
path: root/libcxx/include/__hash_table
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2018-06-04 20:38:23 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2018-06-04 20:38:23 +0000
commitf52318b47b333126c862d9a973d6e59ccaf713dc (patch)
tree7859cdba92b95d143927b8a5b11466c1cfc071f3 /libcxx/include/__hash_table
parentba81d7f1ebfd30bf354390f8656211041d53c176 (diff)
downloadbcm5719-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_table16
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
OpenPOWER on IntegriCloud