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