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