https://bugs.llvm.org/show_bug.cgi?id=36241
On Mon, Feb 5, 2018 at 10:20 AM Hans Wennborg via cfe-commits < cfe-commits@lists.llvm.org> wrote: > This broke the Chromium build, see > https://bugs.chromium.org/p/chromium/issues/detail?id=809050#c2 > > I see there were a lot of changes landed around the same time, so I'm > not sure what to revert here exactly. > > On Sun, Feb 4, 2018 at 2:03 AM, Eric Fiselier via cfe-commits > <cfe-commits@lists.llvm.org> wrote: > > Author: ericwf > > Date: Sat Feb 3 17:03:08 2018 > > New Revision: 324182 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=324182&view=rev > > Log: > > [libc++] Fix PR35491 - std::array of zero-size doesn't work with > non-default constructible types. > > > > Summary: > > This patch fixes llvm.org/PR35491 and LWG2157 ( > https://cplusplus.github.io/LWG/issue2157) > > > > The fix attempts to maintain ABI compatibility by replacing the array > with a instance of `aligned_storage`. > > > > Reviewers: mclow.lists, EricWF > > > > Reviewed By: EricWF > > > > Subscribers: lichray, cfe-commits > > > > Differential Revision: https://reviews.llvm.org/D41223 > > > > Modified: > > libcxx/trunk/include/array > > > libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp > > > libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp > > > > libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp > > libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp > > > > Modified: libcxx/trunk/include/array > > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=324182&r1=324181&r2=324182&view=diff > > > ============================================================================== > > --- libcxx/trunk/include/array (original) > > +++ libcxx/trunk/include/array Sat Feb 3 17:03:08 2018 > > @@ -118,6 +118,55 @@ template <size_t I, class T, size_t N> c > > _LIBCPP_BEGIN_NAMESPACE_STD > > > > template <class _Tp, size_t _Size> > > +struct __array_traits { > > + typedef _Tp _StorageT[_Size]; > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) { > > + return __store; > > + } > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const > _StorageT& __store) { > > + return __store; > > + } > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static void __swap(_StorageT& __lhs, _StorageT& __rhs) { > > + std::swap_ranges(__lhs, __lhs + _Size, __rhs); > > + } > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static void __fill(_StorageT& __arr, _Tp const& __val) { > > + _VSTD::fill_n(__arr, _Size, __val); > > + } > > +}; > > + > > +template <class _Tp> > > +struct __array_traits<_Tp, 0> { > > + typedef typename aligned_storage<sizeof(_Tp), > alignment_of<_Tp>::value>::type _StorageT; > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static _Tp* __data(_StorageT& __store) { > > + _StorageT *__ptr = std::addressof(__store); > > + return reinterpret_cast<_Tp*>(__ptr); > > + } > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static const _Tp* __data(const _StorageT& __store) { > > + const _StorageT *__ptr = std::addressof(__store); > > + return reinterpret_cast<const _Tp*>(__ptr); > > + } > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static void __swap(_StorageT&, _StorageT&) {} > > + > > + _LIBCPP_INLINE_VISIBILITY > > + static void __fill(_StorageT&, _Tp const&) { > > + } > > +}; > > + > > +template <class _Tp, size_t _Size> > > struct _LIBCPP_TEMPLATE_VIS array > > { > > // types: > > @@ -134,31 +183,26 @@ struct _LIBCPP_TEMPLATE_VIS array > > typedef std::reverse_iterator<iterator> reverse_iterator; > > typedef std::reverse_iterator<const_iterator> > const_reverse_iterator; > > > > - value_type __elems_[_Size > 0 ? _Size : 1]; > > + typedef __array_traits<_Tp, _Size> _Traits; > > + typename _Traits::_StorageT __elems_; > > > > // No explicit construct/copy/destroy for aggregate type > > _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) > > - {_VSTD::fill_n(__elems_, _Size, __u);} > > - _LIBCPP_INLINE_VISIBILITY > > - void swap(array& __a) _NOEXCEPT_(_Size == 0 || > __is_nothrow_swappable<_Tp>::value) > > - { __swap_dispatch((std::integral_constant<bool, _Size == 0>()), > __a); } > > + {_Traits::__fill(__elems_, __u);} > > > > _LIBCPP_INLINE_VISIBILITY > > - void __swap_dispatch(std::true_type, array&) {} > > - > > - _LIBCPP_INLINE_VISIBILITY > > - void __swap_dispatch(std::false_type, array& __a) > > - { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} > > + void swap(array& __a) _NOEXCEPT_(_Size == 0 || > __is_nothrow_swappable<_Tp>::value) > > + { _Traits::__swap(__elems_, __a.__elems_); } > > > > // iterators: > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - iterator begin() _NOEXCEPT {return iterator(__elems_);} > > + iterator begin() _NOEXCEPT {return iterator(data());} > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - const_iterator begin() const _NOEXCEPT {return > const_iterator(__elems_);} > > + const_iterator begin() const _NOEXCEPT {return > const_iterator(data());} > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} > > + iterator end() _NOEXCEPT {return iterator(data() + _Size);} > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - const_iterator end() const _NOEXCEPT {return > const_iterator(__elems_ + _Size);} > > + const_iterator end() const _NOEXCEPT {return const_iterator(data() > + _Size);} > > > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > reverse_iterator rbegin() _NOEXCEPT {return > reverse_iterator(end());} > > @@ -201,9 +245,9 @@ struct _LIBCPP_TEMPLATE_VIS array > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 > const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} > > > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - value_type* data() _NOEXCEPT {return __elems_;} > > + value_type* data() _NOEXCEPT {return _Traits::__data(__elems_);} > > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 > > - const value_type* data() const _NOEXCEPT {return __elems_;} > > + const value_type* data() const _NOEXCEPT {return > _Traits::__data(__elems_);} > > }; > > > > template <class _Tp, size_t _Size> > > > > Modified: > libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp > > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp?rev=324182&r1=324181&r2=324182&view=diff > > > ============================================================================== > > --- > libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp > (original) > > +++ > libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp > Sat Feb 3 17:03:08 2018 > > @@ -14,6 +14,14 @@ > > #include <array> > > #include <cassert> > > > > +// std::array is explicitly allowed to be initialized with A a = { > init-list };. > > +// Disable the missing braces warning for this reason. > > +#include "disable_missing_braces_warning.h" > > + > > +struct NoDefault { > > + NoDefault(int) {} > > +}; > > + > > int main() > > { > > { > > @@ -28,4 +36,13 @@ int main() > > C c; > > assert(c.size() == 0); > > } > > + { > > + typedef std::array<NoDefault, 0> C; > > + C c; > > + assert(c.size() == 0); > > + C c1 = {}; > > + assert(c1.size() == 0); > > + C c2 = {{}}; > > + assert(c2.size() == 0); > > + } > > } > > > > Modified: > libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp > > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp?rev=324182&r1=324181&r2=324182&view=diff > > > ============================================================================== > > --- > libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp > (original) > > +++ > libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp > Sat Feb 3 17:03:08 2018 > > @@ -36,4 +36,14 @@ int main() > > T* p = c.data(); > > (void)p; // to placate scan-build > > } > > + { > > + struct NoDefault { > > + NoDefault(int) {} > > + }; > > + typedef NoDefault T; > > + typedef std::array<T, 0> C; > > + C c = {}; > > + T* p = c.data(); > > + assert(p != nullptr); > > + } > > } > > > > Modified: > libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp > > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp?rev=324182&r1=324181&r2=324182&view=diff > > > ============================================================================== > > --- > libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp > (original) > > +++ > libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp > Sat Feb 3 17:03:08 2018 > > @@ -38,6 +38,16 @@ int main() > > const T* p = c.data(); > > (void)p; // to placate scan-build > > } > > + { > > + struct NoDefault { > > + NoDefault(int) {} > > + }; > > + typedef NoDefault T; > > + typedef std::array<T, 0> C; > > + const C c = {}; > > + const T* p = c.data(); > > + assert(p != nullptr); > > + } > > #if TEST_STD_VER > 14 > > { > > typedef std::array<int, 5> C; > > > > Modified: libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp > > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp?rev=324182&r1=324181&r2=324182&view=diff > > > ============================================================================== > > --- libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp > (original) > > +++ libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp Sat > Feb 3 17:03:08 2018 > > @@ -31,4 +31,13 @@ int main() > > *i = 5.5; > > assert(c[0] == 5.5); > > } > > + { > > + struct NoDefault { > > + NoDefault(int) {} > > + }; > > + typedef NoDefault T; > > + typedef std::array<T, 0> C; > > + C c = {}; > > + assert(c.begin() == c.end()); > > + } > > } > > > > > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits@lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits