[PATCH] D47607: [libcxx] Almost fix some UB in <map> and <unordered_map>

Erik Pilkington via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu May 31 15:00:53 PDT 2018


erik.pilkington created this revision.
erik.pilkington added reviewers: rsmith, EricWF, mclow.lists.
Herald added subscribers: christof, kosarev.

<map> and <unordered_map> define `__value_type` as a union between pair<K, V> and pair<const K, V> so that various operations can move into/from these pairs [1]. This is a pretty blatant strict aliasing violation, and has the potential break code that was optimized by TBAA. We can't remove this, not only would that be a significant pessimization, but we are also required to provide a non-const reference to the key_type to implement splicing maps & sets. This patch fixes `__value_type` by downgrading it from "accidentally launch the missiles"-level UB to theoretical UB, namely, instead of type-punning between pairs we just const_cast the key. It's still undefined to mutate a const object, but clang doesn't actually optimize on this rule. Just to be paranoid this patch also `launder()`s to "pick-up" the new value of key whenever we read from it, though this isn't launder's actual use-case. Thanks to @rsmith for the suggestions!

To do this, this patch:

- removes the __nc_value_type data member of the `__value_type` union
- provides access to the pair with `pair<key_type&, mapped_type&>`, which is used to assign through to the pair
- changes `__value_type.__cc` to `__value_type.__get_value()`, the latter calls std::launder in C++1z mode.

https://reviews.llvm.org/D46845 depends on this patch.

[1]: https://stackoverflow.com/a/31667355

Thanks for taking a look!
Erik


Repository:
  rCXX libc++

https://reviews.llvm.org/D47607

Files:
  libcxx/include/__hash_table
  libcxx/include/__tree
  libcxx/include/map
  libcxx/include/unordered_map

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47607.149358.patch
Type: text/x-patch
Size: 25131 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180531/6a7033c0/attachment-0001.bin>


More information about the cfe-commits mailing list