Opened 5 years ago
Last modified 5 years ago
#13275 new Bugs
flat_map's allocator_type constructor could potentially produce invalid output in optimization
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | container |
Version: | Boost 1.65.0 | Severity: | Problem |
Keywords: | flat_map reinterpret_cast allocator_type | Cc: |
Description
In class flat_map, we have constructor:
BOOST_CONTAINER_FORCEINLINE explicit flat_map(const allocator_type& a) : m_flat_tree(container_detail::force<const impl_allocator_type>(a)) {}
This could cause a problem.
Impl_allocator_type is
typedef typename impl_tree_t::allocator_type impl_allocator_type;
And impl_tree_t is
typedef container_detail::flat_tree< container_detail::pair<Key, T>, container_detail::select1st<Key>, Compare, typename allocator_traits<Allocator>::template portable_rebind_alloc <container_detail::pair<Key, T> >::type> impl_tree_t;
container_detail::force() is doing an reinterpret_cast essentially. Let's say argument a is
allocator< std::pair<Key, T> >
Then if we are calling that constructor, we are actually reinterpret_cast argument 'a' from
allocator< std::pair<Key, T> >
to
allocator< container_detail::pair<Key, T> >
While the program could run fine in no-opt because std::pair and container_detail::pair could be very similar and swappable, the program could produce invalid result when compiler turn on optimization. Compiler would find no alias information between allocator<std::pair<Key, T>> and allocator<container_detail::pair<Key, T>>, and think they are not related and move things around to produce invalid result.