From 52cc346d69b9f2dac0ad4aeaa5116d2c484ec319 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 17 Sep 2024 23:54:24 +0800 Subject: [PATCH 01/10] Initially use `[[msvc::no_unique_address]]` for some C++23 components - `in_value_result` - `out_value_result` - `mdspan` - `join_with_view`'s sentinel - `enumerate_view`'s iterator and sentinel - `chunk_view`'s iterator - `slide_view`'s sentinel --- stl/inc/algorithm | 4 +- stl/inc/mdspan | 110 +++++++++--------- stl/inc/ranges | 21 ++-- stl/inc/xutility | 4 +- stl/inc/yvals_core.h | 14 +++ tests/std/test.lst | 4 + .../env.lst | 4 + .../test.compile.pass.cpp | 90 ++++++++++++++ .../env.lst | 7 ++ .../test.compile.pass.cpp | 4 + .../tests/P0009R18_mdspan_extents/test.cpp | 6 - .../P0009R18_mdspan_layout_left/test.cpp | 6 - .../P0009R18_mdspan_layout_right/test.cpp | 6 - .../P0009R18_mdspan_layout_stride/test.cpp | 6 - .../std/tests/P0009R18_mdspan_mdspan/test.cpp | 19 --- tests/std/tests/P0009R18_mdspan_msabi/env.lst | 4 + .../test.compile.pass.cpp | 77 ++++++++++++ .../tests/P0009R18_mdspan_msabi_nvcc/env.lst | 7 ++ .../test.compile.pass.cpp | 4 + 19 files changed, 288 insertions(+), 109 deletions(-) create mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_23/env.lst create mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp create mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst create mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp create mode 100644 tests/std/tests/P0009R18_mdspan_msabi/env.lst create mode 100644 tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp create mode 100644 tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst create mode 100644 tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp diff --git a/stl/inc/algorithm b/stl/inc/algorithm index c16afa7d042..20cd2533630 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -376,8 +376,8 @@ namespace ranges { #if _HAS_CXX23 _EXPORT_STD template struct in_value_result { - /* [[no_unique_address]] */ _In in; - /* [[no_unique_address]] */ _Ty value; + _MSVC_NO_UNIQUE_ADDRESS _In in; + _MSVC_NO_UNIQUE_ADDRESS _Ty value; template requires convertible_to && convertible_to diff --git a/stl/inc/mdspan b/stl/inc/mdspan index 3bb2292c5e2..3ad6ba67df3 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -23,8 +23,8 @@ _STL_DISABLE_CLANG_WARNINGS #undef new // TRANSITION, non-_Ugly attribute tokens -#pragma push_macro("empty_bases") -#undef empty_bases +#pragma push_macro("msvc") +#undef msvc _STD_BEGIN template @@ -1072,37 +1072,37 @@ concept _Elidable_layout_mapping = || (same_as<_LayoutPolicy, layout_stride> && _Extents::rank() == 0); template -struct _Mdspan_mapping_base { +struct _Mdspan_mapping_holder { _STL_INTERNAL_STATIC_ASSERT(_Is_extents<_Extents>); using _Mapping = _LayoutPolicy::template mapping<_Extents>; - constexpr _Mdspan_mapping_base() noexcept = default; + constexpr _Mdspan_mapping_holder() noexcept = default; - constexpr explicit _Mdspan_mapping_base(const _Extents& _Exts) : _Map(_Exts) {} + constexpr explicit _Mdspan_mapping_holder(const _Extents& _Exts) : _Map(_Exts) {} - constexpr explicit _Mdspan_mapping_base(_Extents&& _Exts) : _Map(_STD move(_Exts)) {} + constexpr explicit _Mdspan_mapping_holder(_Extents&& _Exts) : _Map(_STD move(_Exts)) {} template - constexpr explicit _Mdspan_mapping_base(const _OtherMapping& _Map_) : _Map(_Map_) {} + constexpr explicit _Mdspan_mapping_holder(const _OtherMapping& _Map_) : _Map(_Map_) {} - _Mapping _Map = _Mapping(); + _MSVC_NO_UNIQUE_ADDRESS _Mapping _Map = _Mapping(); }; template _LayoutPolicy> -struct _Mdspan_mapping_base<_Extents, _LayoutPolicy> { +struct _Mdspan_mapping_holder<_Extents, _LayoutPolicy> { _STL_INTERNAL_STATIC_ASSERT(_Is_extents<_Extents>); using _Mapping = _LayoutPolicy::template mapping<_Extents>; - constexpr _Mdspan_mapping_base() noexcept = default; + constexpr _Mdspan_mapping_holder() noexcept = default; - constexpr explicit _Mdspan_mapping_base(const _Extents&) noexcept {} + constexpr explicit _Mdspan_mapping_holder(const _Extents&) noexcept {} - constexpr explicit _Mdspan_mapping_base(_Extents&&) noexcept {} + constexpr explicit _Mdspan_mapping_holder(_Extents&&) noexcept {} template - constexpr explicit _Mdspan_mapping_base(const _OtherMapping& _Map_) { + constexpr explicit _Mdspan_mapping_holder(const _OtherMapping& _Map_) { // NB: Constructing _Mapping from _OtherMapping may have side effects - we should create a temporary. if constexpr (!_Elidable_layout_mapping) { (void) _Mapping{_Map_}; @@ -1116,21 +1116,21 @@ template concept _Elidable_accessor_policy = _Is_specialization_v<_AccessorPolicy, default_accessor>; template -struct _Mdspan_accessor_base { - constexpr _Mdspan_accessor_base() noexcept = default; +struct _Mdspan_accessor_holder { + constexpr _Mdspan_accessor_holder() noexcept = default; template - constexpr explicit _Mdspan_accessor_base(const _OtherAccessorPolicy& _Acc_) : _Acc(_Acc_) {} + constexpr explicit _Mdspan_accessor_holder(const _OtherAccessorPolicy& _Acc_) : _Acc(_Acc_) {} - _AccessorPolicy _Acc = _AccessorPolicy(); + _MSVC_NO_UNIQUE_ADDRESS _AccessorPolicy _Acc = _AccessorPolicy(); }; template <_Elidable_accessor_policy _AccessorPolicy> -struct _Mdspan_accessor_base<_AccessorPolicy> { - constexpr _Mdspan_accessor_base() noexcept = default; +struct _Mdspan_accessor_holder<_AccessorPolicy> { + constexpr _Mdspan_accessor_holder() noexcept = default; template - constexpr explicit _Mdspan_accessor_base(const _OtherAccessorPolicy& _Acc_) { + constexpr explicit _Mdspan_accessor_holder(const _OtherAccessorPolicy& _Acc_) { // NB: Constructing _AccessorPolicy from _OtherAccessorPolicy may have side effects - we should create a // temporary. if constexpr (!_Elidable_accessor_policy<_OtherAccessorPolicy>) { @@ -1159,8 +1159,7 @@ _NODISCARD constexpr _IndexType _Mdspan_checked_index_cast(_OtherIndexType&& _Id _EXPORT_STD template > -class __declspec(empty_bases) mdspan : private _Mdspan_mapping_base<_Extents, _LayoutPolicy>, - private _Mdspan_accessor_base<_AccessorPolicy> { +class mdspan { public: using extents_type = _Extents; using layout_type = _LayoutPolicy; @@ -1175,9 +1174,6 @@ public: using reference = accessor_type::reference; private: - using _Mapping_base = _Mdspan_mapping_base; - using _Accessor_base = _Mdspan_accessor_base; - static_assert( sizeof(element_type) > 0, "ElementType must be a complete type (N4950 [mdspan.mdspan.overview]/2.1)."); static_assert( @@ -1207,7 +1203,7 @@ public: } _NODISCARD constexpr index_type extent(_In_range_(<, extents_type::_Rank) const rank_type _Idx) const noexcept { - return this->_Map.extents().extent(_Idx); + return _Mapping._Map.extents().extent(_Idx); } constexpr mdspan() noexcept(is_nothrow_default_constructible_v @@ -1228,8 +1224,7 @@ public: constexpr explicit mdspan(data_handle_type _Ptr_, _OtherIndexTypes... _Exts) noexcept(is_nothrow_constructible_v && is_nothrow_default_constructible_v) // strengthened - : _Mapping_base(extents_type{static_cast(_STD move(_Exts))...}), _Accessor_base(), - _Ptr(_STD move(_Ptr_)) {} + : _Mapping(extents_type{static_cast(_STD move(_Exts))...}), _Accessor(), _Ptr(_STD move(_Ptr_)) {} template requires is_convertible_v @@ -1239,7 +1234,7 @@ public: constexpr explicit(_Size != rank_dynamic()) mdspan(data_handle_type _Ptr_, span<_OtherIndexType, _Size> _Exts) noexcept(is_nothrow_constructible_v && is_nothrow_default_constructible_v) // strengthened - : _Mapping_base(extents_type{_Exts}), _Accessor_base(), _Ptr(_STD move(_Ptr_)) {} + : _Mapping(extents_type{_Exts}), _Accessor(), _Ptr(_STD move(_Ptr_)) {} template requires is_convertible_v @@ -1250,23 +1245,23 @@ public: mdspan(data_handle_type _Ptr_, const array<_OtherIndexType, _Size>& _Exts) noexcept(is_nothrow_constructible_v && is_nothrow_default_constructible_v) // strengthened - : _Mapping_base(extents_type{_Exts}), _Accessor_base(), _Ptr(_STD move(_Ptr_)) {} + : _Mapping(extents_type{_Exts}), _Accessor(), _Ptr(_STD move(_Ptr_)) {} constexpr mdspan(data_handle_type _Ptr_, const extents_type& _Exts) noexcept(is_nothrow_constructible_v && is_nothrow_default_constructible_v) // strengthened requires is_constructible_v && is_default_constructible_v - : _Mapping_base(_Exts), _Accessor_base(), _Ptr(_STD move(_Ptr_)) {} + : _Mapping(_Exts), _Accessor(), _Ptr(_STD move(_Ptr_)) {} constexpr mdspan(data_handle_type _Ptr_, const mapping_type& _Map_) noexcept(is_nothrow_copy_constructible_v && is_nothrow_default_constructible_v) // strengthened requires is_default_constructible_v - : _Mapping_base(_Map_), _Accessor_base(), _Ptr(_STD move(_Ptr_)) {} + : _Mapping(_Map_), _Accessor(), _Ptr(_STD move(_Ptr_)) {} constexpr mdspan(data_handle_type _Ptr_, const mapping_type& _Map_, const accessor_type& _Acc_) noexcept( is_nothrow_copy_constructible_v && is_nothrow_copy_constructible_v) // strengthened - : _Mapping_base(_Map_), _Accessor_base(_Acc_), _Ptr(_STD move(_Ptr_)) {} + : _Mapping(_Map_), _Accessor(_Acc_), _Ptr(_STD move(_Ptr_)) {} template requires is_constructible_v&> @@ -1279,7 +1274,7 @@ public: && is_nothrow_constructible_v&> && is_nothrow_constructible_v) // strengthened - : _Mapping_base(_Other.mapping()), _Accessor_base(_Other.accessor()), _Ptr(_Other.data_handle()) { + : _Mapping(_Other.mapping()), _Accessor(_Other.accessor()), _Ptr(_Other.data_handle()) { static_assert(is_constructible_v, "The data_handle_type must be constructible from const typename OtherAccessor::data_handle_type& (N4950 " "[mdspan.mdspan.cons]/20.1)."); @@ -1345,20 +1340,21 @@ public: _NODISCARD constexpr size_type size() const noexcept { #if _CONTAINER_DEBUG_LEVEL > 0 if constexpr (rank_dynamic() != 0) { - _STL_VERIFY(this->_Map.extents().template _Is_dynamic_multidim_index_space_size_representable(), + _STL_VERIFY( + _Mapping._Map.extents().template _Is_dynamic_multidim_index_space_size_representable(), "The size of the multidimensional index space extents() must be representable as a value of type " "size_type (N4950 [mdspan.mdspan.members]/7)."); } #endif // _CONTAINER_DEBUG_LEVEL > 0 return static_cast( - _Fwd_prod_of_extents::_Calculate(this->_Map.extents(), extents_type::_Rank)); + _Fwd_prod_of_extents::_Calculate(_Mapping._Map.extents(), extents_type::_Rank)); } _NODISCARD constexpr bool empty() const noexcept { if constexpr (extents_type::_Multidim_index_space_size_is_always_zero) { return true; } else { - const extents_type& _Exts = this->_Map.extents(); + const extents_type& _Exts = _Mapping._Map.extents(); for (rank_type _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { if (_Exts.extent(_Idx) == 0) { return true; @@ -1372,16 +1368,16 @@ public: swap(_Left._Ptr, _Right._Ptr); // intentional ADL if constexpr (!_Elidable_layout_mapping) { - swap(_Left._Map, _Right._Map); // intentional ADL + swap(_Left._Mapping._Map, _Right._Mapping._Map); // intentional ADL } if constexpr (!_Elidable_accessor_policy) { - swap(_Left._Acc, _Right._Acc); // intentional ADL + swap(_Left._Accessor._Acc, _Right._Accessor._Acc); // intentional ADL } } _NODISCARD constexpr const extents_type& extents() const noexcept { - return this->_Map.extents(); + return _Mapping._Map.extents(); } _NODISCARD constexpr const data_handle_type& data_handle() const noexcept { @@ -1389,11 +1385,11 @@ public: } _NODISCARD constexpr const mapping_type& mapping() const noexcept { - return this->_Map; + return _Mapping._Map; } _NODISCARD constexpr const accessor_type& accessor() const noexcept { - return this->_Acc; + return _Accessor._Acc; } _NODISCARD static constexpr bool is_always_unique() noexcept /* strengthened */ { @@ -1411,37 +1407,41 @@ public: return _Result; } - _NODISCARD constexpr bool is_unique() const noexcept(noexcept(this->_Map.is_unique())) /* strengthened */ { - return this->_Map.is_unique(); + _NODISCARD constexpr bool is_unique() const noexcept(noexcept(_Mapping._Map.is_unique())) /* strengthened */ { + return _Mapping._Map.is_unique(); } - _NODISCARD constexpr bool is_exhaustive() const noexcept(noexcept(this->_Map.is_exhaustive())) /* strengthened */ { - return this->_Map.is_exhaustive(); + _NODISCARD constexpr bool is_exhaustive() const + noexcept(noexcept(_Mapping._Map.is_exhaustive())) /* strengthened */ { + return _Mapping._Map.is_exhaustive(); } - _NODISCARD constexpr bool is_strided() const noexcept(noexcept(this->_Map.is_strided())) /* strengthened */ { - return this->_Map.is_strided(); + _NODISCARD constexpr bool is_strided() const noexcept(noexcept(_Mapping._Map.is_strided())) /* strengthened */ { + return _Mapping._Map.is_strided(); } _NODISCARD constexpr index_type stride(const rank_type _Idx) const - noexcept(noexcept(this->_Map.stride(_Idx))) /* strengthened */ { - return this->_Map.stride(_Idx); + noexcept(noexcept(_Mapping._Map.stride(_Idx))) /* strengthened */ { + return _Mapping._Map.stride(_Idx); } private: template _NODISCARD constexpr reference _Access_impl(_OtherIndexTypes... _Indices) const - noexcept(noexcept(this->_Acc.access(_Ptr, static_cast(this->_Map(_Indices...))))) { + noexcept(noexcept(_Accessor._Acc.access(_Ptr, static_cast(_Mapping._Map(_Indices...))))) { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); #if _CONTAINER_DEBUG_LEVEL > 0 - _STL_VERIFY(this->_Map.extents()._Contains_multidimensional_index(make_index_sequence{}, _Indices...), + _STL_VERIFY( + _Mapping._Map.extents()._Contains_multidimensional_index(make_index_sequence{}, _Indices...), "I must be a multidimensional index in extents() (N4950 [mdspan.mdspan.members]/3)."); #endif // _CONTAINER_DEBUG_LEVEL > 0 - return this->_Acc.access(_Ptr, static_cast(this->_Map(_Indices...))); + return _Accessor._Acc.access(_Ptr, static_cast(_Mapping._Map(_Indices...))); } - /* [[no_unique_address]] */ data_handle_type _Ptr = data_handle_type(); + _MSVC_NO_UNIQUE_ADDRESS _Mdspan_mapping_holder _Mapping; + _MSVC_NO_UNIQUE_ADDRESS _Mdspan_accessor_holder _Accessor; + _MSVC_NO_UNIQUE_ADDRESS data_handle_type _Ptr = data_handle_type(); }; template @@ -1478,7 +1478,7 @@ mdspan(const typename _AccessorType::data_handle_type&, const _MappingType&, _STD_END // TRANSITION, non-_Ugly attribute tokens -#pragma pop_macro("empty_bases") +#pragma pop_macro("msvc") #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS diff --git a/stl/inc/ranges b/stl/inc/ranges index bb5eca79ce3..1f3b46ff7be 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -31,6 +31,10 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +// TRANSITION, non-_Ugly attribute tokens +#pragma push_macro("msvc") +#undef msvc + _STD_BEGIN namespace ranges { // MUCH machinery defined in , some in <__msvc_ranges_to.hpp> @@ -1087,7 +1091,7 @@ namespace ranges { using _Index_type = conditional_t, ptrdiff_t, _Bo>; const _Ty* _Value{}; - /* [[no_unique_address]] */ _Index_type _Current{}; + _Index_type _Current{}; constexpr explicit _Iterator(const _Ty* _Val, _Index_type _Bo_ = _Index_type{}) noexcept // strengthened : _Value(_Val), _Current(_Bo_) { @@ -3453,7 +3457,7 @@ namespace ranges { using _Parent_t = _Maybe_const<_Const, join_with_view>; using _Base = _Maybe_const<_Const, _Vw>; - /* [[no_unique_address]] */ sentinel_t<_Base> _Last{}; + _MSVC_NO_UNIQUE_ADDRESS sentinel_t<_Base> _Last{}; constexpr explicit _Sentinel(_Parent_t& _Parent) noexcept(noexcept(_RANGES end(_Parent._Range)) @@ -5130,7 +5134,7 @@ namespace ranges { using _Base_iterator = iterator_t<_Base_t>; using _Reference_type = tuple, range_reference_t<_Base_t>>; - /* [[no_unique_address]] */ _Base_iterator _Current{}; + _MSVC_NO_UNIQUE_ADDRESS _Base_iterator _Current{}; range_difference_t<_Base_t> _Pos = 0; constexpr explicit _Iterator(_Base_iterator _Current_, range_difference_t<_Base_t> _Pos_) @@ -5290,7 +5294,7 @@ namespace ranges { using _Base_t = _Maybe_const<_Const, _Vw>; using _Base_sentinel = sentinel_t<_Base_t>; - /* [[no_unique_address]] */ _Base_sentinel _End{}; + _MSVC_NO_UNIQUE_ADDRESS _Base_sentinel _End{}; constexpr explicit _Sentinel(_Base_sentinel _End_) noexcept(is_nothrow_move_constructible_v<_Base_sentinel>) // strengthened @@ -5726,8 +5730,8 @@ namespace ranges { using _Base_iterator = iterator_t<_Base>; using _Base_sentinel = sentinel_t<_Base>; - /* [[no_unique_address]] */ _Base_iterator _Current{}; - /* [[no_unique_address]] */ _Base_sentinel _End{}; + _MSVC_NO_UNIQUE_ADDRESS _Base_iterator _Current{}; + _MSVC_NO_UNIQUE_ADDRESS _Base_sentinel _End{}; range_difference_t<_Base> _Count = 0; range_difference_t<_Base> _Missing = 0; @@ -6285,7 +6289,7 @@ namespace ranges { class _Sentinel { private: friend slide_view; - /* [[no_unique_address]] */ sentinel_t<_Vw> _Last{}; + _MSVC_NO_UNIQUE_ADDRESS sentinel_t<_Vw> _Last{}; constexpr explicit _Sentinel(sentinel_t<_Vw> _Last_) noexcept(is_nothrow_move_constructible_v>) /* strengthened */ @@ -9253,6 +9257,9 @@ _EXPORT_STD namespace views = ranges::views; _STD_END +// TRANSITION, non-_Ugly attribute tokens +#pragma pop_macro("msvc") + #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) diff --git a/stl/inc/xutility b/stl/inc/xutility index 6e791d549a9..acb03e1c020 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -4875,8 +4875,8 @@ namespace ranges { #if _HAS_CXX23 _EXPORT_STD template struct out_value_result { - /* [[no_unique_address]] */ _Out out; - /* [[no_unique_address]] */ _Ty value; + _MSVC_NO_UNIQUE_ADDRESS _Out out; + _MSVC_NO_UNIQUE_ADDRESS _Ty value; template <_Convertible_from _OOut, _Convertible_from _TTy> constexpr operator out_value_result<_OOut, _TTy>() const& { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index bbf9cbd75f2..0729c797db1 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -746,6 +746,20 @@ #define _MSVC_LIFETIMEBOUND #endif +#if _HAS_CXX23 // TRANSITION, ABI, should just use [[no_unique_address]] when _HAS_CXX20. +// Should we enable use of [[msvc::no_unique_address]] or [[no_unique_address]] to allow potentially-overlapping member +// subobjects? +#if _HAS_MSVC_ATTRIBUTE(no_unique_address) +#define _MSVC_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] +#elif __has_cpp_attribute(no_unique_address) // TRANSITION, DevCom-10747012, EDG recognizes [[no_unique_address]]. +#define _MSVC_NO_UNIQUE_ADDRESS [[no_unique_address]] +#elif defined(__INTEL_COMPILER) // ICC is not properly supported. +#define _MSVC_NO_UNIQUE_ADDRESS +#else +#error Either [[msvc::no_unique_address]] or [[no_unique_address]] must be supported because this is ABI-critical. +#endif +#endif // _HAS_CXX23 + #undef _HAS_MSVC_ATTRIBUTE #pragma pop_macro("lifetimebound") #pragma pop_macro("intrinsic") diff --git a/tests/std/test.lst b/tests/std/test.lst index fde8f2a1d2c..484859f94a8 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -189,6 +189,8 @@ tests\GH_001103_countl_zero_correctness tests\GH_001105_custom_streambuf_throws tests\GH_001123_random_cast_out_of_range tests\GH_001277_num_get_bad_grouping +tests\GH_001394_msvc_no_unique_address_23 +tests\GH_001394_msvc_no_unique_address_nvcc_23 tests\GH_001411_core_headers tests\GH_001530_binomial_accuracy tests\GH_001541_case_sensitive_boolalpha @@ -274,6 +276,8 @@ tests\P0009R18_mdspan_layout_stride tests\P0009R18_mdspan_layout_stride_death tests\P0009R18_mdspan_mdspan tests\P0009R18_mdspan_mdspan_death +tests\P0009R18_mdspan_msabi +tests\P0009R18_mdspan_msabi_nvcc tests\P0019R8_atomic_ref tests\P0024R2_parallel_algorithms_adjacent_difference tests\P0024R2_parallel_algorithms_adjacent_find diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_23/env.lst b/tests/std/tests/GH_001394_msvc_no_unique_address_23/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_23/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp new file mode 100644 index 00000000000..e4f319695a3 --- /dev/null +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Tests MSVC STL specific behavior on ABI. + +#include +#include +#include +#include +#include + +using namespace std; + +static_assert(sizeof(ranges::in_value_result) == sizeof(int)); +static_assert(sizeof(ranges::in_value_result) == sizeof(int)); +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v>); +#endif // ^^^ no workaround ^^^ + +static_assert(sizeof(ranges::out_value_result) == sizeof(int)); +static_assert(sizeof(ranges::out_value_result) == sizeof(int)); +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v>); +#endif // ^^^ no workaround ^^^ + +struct stateless_input_it { + using value_type = int; + using difference_type = ptrdiff_t; + + int operator*() const noexcept { + return 42; + } + + stateless_input_it& operator++() noexcept { + return *this; + } + + stateless_input_it operator++(int) noexcept { + return {}; + } +}; + +struct stateless_forward_it { + using value_type = int; + using difference_type = ptrdiff_t; + + int operator*() const noexcept { + return 42; + } + + stateless_forward_it& operator++() noexcept { + return *this; + } + + stateless_forward_it operator++(int) noexcept { + return {}; + } + + friend bool operator==(stateless_forward_it, stateless_forward_it) = default; +}; + +static_assert(input_iterator); +static_assert(forward_iterator); + +using test_range = ranges::subrange; +using test_outer_range = ranges::subrange; +using stateless_input_range = ranges::subrange; +using stateless_fwd_range = ranges::subrange; +using stateless_fwd_common_range = ranges::subrange; + +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v); +#endif // ^^^ no workaround ^^^ + +static_assert(sizeof((stateless_input_range{} | views::enumerate).begin()) == sizeof(ptrdiff_t)); +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v); +#endif // ^^^ no workaround ^^^ + +static_assert(sizeof((stateless_fwd_range{} | views::chunk(42)).begin()) == sizeof(ptrdiff_t) * 2); +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(sizeof((stateless_fwd_common_range{} | views::chunk(42)).begin()) == sizeof(ptrdiff_t) * 2); +#endif // ^^^ no workaround ^^^ + +static_assert(sizeof((stateless_fwd_range{} | views::chunk_by(ranges::less{})).begin()) == sizeof(void*) * 2); +static_assert(sizeof((stateless_fwd_common_range{} | views::chunk_by(ranges::less{})).begin()) == sizeof(void*) * 2); + +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v); +#endif // ^^^ no workaround ^^^ diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst new file mode 100644 index 00000000000..7b5b812f1de --- /dev/null +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst @@ -0,0 +1,7 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +PM_COMPILER="nvcc" PM_CL="--x cu -Xcompiler -std:c++latest,-Od,-EHsc,-nologo,-W4,-WX,-openmp" +RUNALL_CROSSLIST +PM_CL="-Xcompiler -MT" +PM_CL="--debug -Xcompiler -MTd" diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp new file mode 100644 index 00000000000..4d50ef74940 --- /dev/null +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "../GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp" diff --git a/tests/std/tests/P0009R18_mdspan_extents/test.cpp b/tests/std/tests/P0009R18_mdspan_extents/test.cpp index 2dedead9cc9..90163bfe391 100644 --- a/tests/std/tests/P0009R18_mdspan_extents/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_extents/test.cpp @@ -545,12 +545,6 @@ static_assert(all_extents_dynamic, 7>); static_assert(all_extents_dynamic, 8>); static_assert(all_extents_dynamic, 9>); -// When 'E::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true (MSVC STL specific behavior) -static_assert(!is_empty_v>); -static_assert(!is_empty_v>); -static_assert(is_empty_v>); -static_assert(is_empty_v>); - int main() { static_assert(test()); test(); diff --git a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp index c48709d1875..470d79e1671 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp @@ -485,12 +485,6 @@ constexpr void check_correctness() { } } -// When 'M::extents_type::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true (MSVC STL specific behavior) -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(is_empty_v>>); -static_assert(is_empty_v>>); - constexpr bool test() { check_members_with_various_extents([](const E& e) { check_members(e, make_index_sequence{}); }); if (!is_constant_evaluated()) { // too heavy for compile time diff --git a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp index ef08dd7e9a9..0949dfa66d7 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp @@ -516,12 +516,6 @@ constexpr void check_correctness() { } } -// When 'M::extents_type::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true (MSVC STL specific behavior) -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(is_empty_v>>); -static_assert(is_empty_v>>); - constexpr bool test() { check_members_with_various_extents([](const E& e) { check_members(e, make_index_sequence{}); }); if (!is_constant_evaluated()) { // too heavy for compile time diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 5f34b8c1541..9ebb862c3cc 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -820,12 +820,6 @@ constexpr void check_correctness() { } } -// When 'M::extents_type::rank()' is equal to 0 then 'is_empty_v' should be true (MSVC STL specific behavior) -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(is_empty_v>>); - constexpr bool test() { // Check signed integers check_members(extents{5}, array{1}); diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index c68533ccd0e..9ed92972f99 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -1359,25 +1359,6 @@ constexpr void check_deduction_guides() { } } -// When -// * 'Mds::accessor_type' is a specialization of 'default_accessor', and -// * 'Mds::layout_type' is -// * 'layout_left' or 'layout_right' and 'Mds::extents_type::rank_dynamic() == 0', or -// * 'layout_stride' and 'Mds::extents_type::rank() == 0' -// then 'sizeof(Mds) == sizeof(void*)' (MSVC STL specific behavior). -static_assert(sizeof(mdspan, layout_left>) == sizeof(void*)); -static_assert(sizeof(mdspan, layout_left>) > sizeof(void*)); -static_assert(sizeof(mdspan, layout_left, TrivialAccessor>) > sizeof(void*)); - -static_assert(sizeof(mdspan, layout_right>) == sizeof(void*)); -static_assert(sizeof(mdspan, layout_right>) > sizeof(void*)); -static_assert(sizeof(mdspan, layout_right, TrivialAccessor>) > sizeof(void*)); - -static_assert(sizeof(mdspan, layout_stride>) == sizeof(void*)); -static_assert(sizeof(mdspan, layout_stride>) > sizeof(void*)); -static_assert(sizeof(mdspan, layout_stride>) > sizeof(void*)); -static_assert(sizeof(mdspan, layout_stride, TrivialAccessor>) > sizeof(void*)); - constexpr bool test() { check_modeled_concepts_and_member_types, layout_left, default_accessor>(); check_modeled_concepts_and_member_types, layout_right, default_accessor>(); diff --git a/tests/std/tests/P0009R18_mdspan_msabi/env.lst b/tests/std/tests/P0009R18_mdspan_msabi/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/P0009R18_mdspan_msabi/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp new file mode 100644 index 00000000000..79d84bf48f9 --- /dev/null +++ b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Tests MSVC STL specific behavior on ABI. + +#include +#include +#include + +#include + +using namespace std; + +template +struct TrivialAccessor { + using offset_policy = TrivialAccessor; + using element_type = ElementType; + using reference = ElementType&; + using data_handle_type = ElementType*; + + constexpr reference access(data_handle_type handle, size_t off) const noexcept { + return handle[off]; + } + + constexpr data_handle_type offset(data_handle_type handle, size_t off) const noexcept { + return handle + off; + } + + int member; +}; + +static_assert(check_accessor_policy_requirements>()); +static_assert(is_trivial_v>); + + +// When 'E::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true +static_assert(!is_empty_v>); +static_assert(!is_empty_v>); +static_assert(is_empty_v>); +static_assert(is_empty_v>); + +// When 'M::extents_type::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true +static_assert(!is_empty_v>>); +static_assert(!is_empty_v>>); +static_assert(is_empty_v>>); +static_assert(is_empty_v>>); + +// When 'M::extents_type::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true +static_assert(!is_empty_v>>); +static_assert(!is_empty_v>>); +static_assert(is_empty_v>>); +static_assert(is_empty_v>>); + +// When 'M::extents_type::rank()' is equal to 0 then 'is_empty_v' should be true +static_assert(!is_empty_v>>); +static_assert(!is_empty_v>>); +static_assert(!is_empty_v>>); +static_assert(is_empty_v>>); + +// When +// * 'Mds::accessor_type' is a specialization of 'default_accessor', and +// * 'Mds::layout_type' is +// * 'layout_left' or 'layout_right' and 'Mds::extents_type::rank_dynamic() == 0', or +// * 'layout_stride' and 'Mds::extents_type::rank() == 0' +// then 'sizeof(Mds) == sizeof(void*)' (MSVC STL specific behavior). +static_assert(sizeof(mdspan, layout_left>) == sizeof(void*)); +static_assert(sizeof(mdspan, layout_left>) > sizeof(void*)); +static_assert(sizeof(mdspan, layout_left, TrivialAccessor>) > sizeof(void*)); + +static_assert(sizeof(mdspan, layout_right>) == sizeof(void*)); +static_assert(sizeof(mdspan, layout_right>) > sizeof(void*)); +static_assert(sizeof(mdspan, layout_right, TrivialAccessor>) > sizeof(void*)); + +static_assert(sizeof(mdspan, layout_stride>) == sizeof(void*)); +static_assert(sizeof(mdspan, layout_stride>) > sizeof(void*)); +static_assert(sizeof(mdspan, layout_stride>) > sizeof(void*)); +static_assert(sizeof(mdspan, layout_stride, TrivialAccessor>) > sizeof(void*)); diff --git a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst new file mode 100644 index 00000000000..7b5b812f1de --- /dev/null +++ b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst @@ -0,0 +1,7 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +PM_COMPILER="nvcc" PM_CL="--x cu -Xcompiler -std:c++latest,-Od,-EHsc,-nologo,-W4,-WX,-openmp" +RUNALL_CROSSLIST +PM_CL="-Xcompiler -MT" +PM_CL="--debug -Xcompiler -MTd" diff --git a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp new file mode 100644 index 00000000000..f32ef7fe425 --- /dev/null +++ b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "../P0009R18_mdspan_msabi/test.compile.pass.cpp" From 593255a8c72da3a5f87120118c6b53b281555128 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 19 Sep 2024 09:11:21 +0800 Subject: [PATCH 02/10] Revert test coverage for NVCC and try to handle ICC --- stl/inc/yvals_core.h | 2 -- tests/std/test.lst | 2 -- .../tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst | 7 ------- .../test.compile.pass.cpp | 4 ---- tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst | 7 ------- .../tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp | 4 ---- 6 files changed, 26 deletions(-) delete mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst delete mode 100644 tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp delete mode 100644 tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst delete mode 100644 tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 0729c797db1..6b248dc4017 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -753,8 +753,6 @@ #define _MSVC_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] #elif __has_cpp_attribute(no_unique_address) // TRANSITION, DevCom-10747012, EDG recognizes [[no_unique_address]]. #define _MSVC_NO_UNIQUE_ADDRESS [[no_unique_address]] -#elif defined(__INTEL_COMPILER) // ICC is not properly supported. -#define _MSVC_NO_UNIQUE_ADDRESS #else #error Either [[msvc::no_unique_address]] or [[no_unique_address]] must be supported because this is ABI-critical. #endif diff --git a/tests/std/test.lst b/tests/std/test.lst index 484859f94a8..1b66fa257b7 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -190,7 +190,6 @@ tests\GH_001105_custom_streambuf_throws tests\GH_001123_random_cast_out_of_range tests\GH_001277_num_get_bad_grouping tests\GH_001394_msvc_no_unique_address_23 -tests\GH_001394_msvc_no_unique_address_nvcc_23 tests\GH_001411_core_headers tests\GH_001530_binomial_accuracy tests\GH_001541_case_sensitive_boolalpha @@ -277,7 +276,6 @@ tests\P0009R18_mdspan_layout_stride_death tests\P0009R18_mdspan_mdspan tests\P0009R18_mdspan_mdspan_death tests\P0009R18_mdspan_msabi -tests\P0009R18_mdspan_msabi_nvcc tests\P0019R8_atomic_ref tests\P0024R2_parallel_algorithms_adjacent_difference tests\P0024R2_parallel_algorithms_adjacent_find diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst deleted file mode 100644 index 7b5b812f1de..00000000000 --- a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/env.lst +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -PM_COMPILER="nvcc" PM_CL="--x cu -Xcompiler -std:c++latest,-Od,-EHsc,-nologo,-W4,-WX,-openmp" -RUNALL_CROSSLIST -PM_CL="-Xcompiler -MT" -PM_CL="--debug -Xcompiler -MTd" diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp deleted file mode 100644 index 4d50ef74940..00000000000 --- a/tests/std/tests/GH_001394_msvc_no_unique_address_nvcc_23/test.compile.pass.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include "../GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp" diff --git a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst deleted file mode 100644 index 7b5b812f1de..00000000000 --- a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/env.lst +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -PM_COMPILER="nvcc" PM_CL="--x cu -Xcompiler -std:c++latest,-Od,-EHsc,-nologo,-W4,-WX,-openmp" -RUNALL_CROSSLIST -PM_CL="-Xcompiler -MT" -PM_CL="--debug -Xcompiler -MTd" diff --git a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp b/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp deleted file mode 100644 index f32ef7fe425..00000000000 --- a/tests/std/tests/P0009R18_mdspan_msabi_nvcc/test.compile.pass.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include "../P0009R18_mdspan_msabi/test.compile.pass.cpp" From 68d052f484d44d4463ac12fa1212e9011871890f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 20 Sep 2024 17:43:23 +0800 Subject: [PATCH 03/10] Also handle `elements_of` --- stl/inc/xmemory | 11 +++++++++-- .../test.compile.pass.cpp | 12 ++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 3aa11f488c8..9396b712958 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -25,6 +25,10 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +// TRANSITION, non-_Ugly attribute tokens +#pragma push_macro("msvc") +#undef msvc + _STD_BEGIN template _NODISCARD constexpr auto _Unfancy(_Ptrty _Ptr) noexcept { // converts from a fancy pointer to a plain pointer @@ -2596,8 +2600,8 @@ namespace ranges { _EXPORT_STD template #endif // ^^^ !defined(__cpp_lib_byte) ^^^ struct elements_of { - /* [[no_unique_address]] */ _Rng range; - /* [[no_unique_address]] */ _Alloc allocator{}; + _MSVC_NO_UNIQUE_ADDRESS _Rng range; + _MSVC_NO_UNIQUE_ADDRESS _Alloc allocator{}; }; #if defined(__cpp_lib_byte) @@ -2649,6 +2653,9 @@ _STD_END #define _CONTAINER_EMPLACE_RETURN void #endif // ^^^ !_HAS_CXX17 ^^^ +// TRANSITION, non-_Ugly attribute tokens +#pragma pop_macro("msvc") + #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp index e4f319695a3..161b7394e4e 100644 --- a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include @@ -88,3 +90,13 @@ static_assert(sizeof((stateless_fwd_common_range{} | views::chunk_by(ranges::les #ifndef __EDG__ // TRANSITION, DevCom-10747012 static_assert(is_empty_v); #endif // ^^^ no workaround ^^^ + +static_assert(sizeof(elements_of>) == sizeof(int[1])); +static_assert(sizeof(elements_of>) == sizeof(int (*)[1])); +static_assert(sizeof(elements_of, pmr::polymorphic_allocator>) + == sizeof(pmr::polymorphic_allocator)); +static_assert(sizeof(elements_of, allocator>) == 1); + +#ifndef __EDG__ // TRANSITION, DevCom-10747012 +static_assert(is_empty_v, allocator>>); +#endif // ^^^ no workaround ^^^ From 549bc9072d407ac98c25117f61fcde5d2e7d9e6b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 20 Sep 2024 18:10:56 +0800 Subject: [PATCH 04/10] `ranges::`! --- .../test.compile.pass.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp index 161b7394e4e..d0c443ef647 100644 --- a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp @@ -91,11 +91,11 @@ static_assert(sizeof((stateless_fwd_common_range{} | views::chunk_by(ranges::les static_assert(is_empty_v); #endif // ^^^ no workaround ^^^ -static_assert(sizeof(elements_of>) == sizeof(int[1])); -static_assert(sizeof(elements_of>) == sizeof(int (*)[1])); -static_assert(sizeof(elements_of, pmr::polymorphic_allocator>) +static_assert(sizeof(ranges::elements_of>) == sizeof(int[1])); +static_assert(sizeof(ranges::elements_of>) == sizeof(int (*)[1])); +static_assert(sizeof(ranges::elements_of, pmr::polymorphic_allocator>) == sizeof(pmr::polymorphic_allocator)); -static_assert(sizeof(elements_of, allocator>) == 1); +static_assert(sizeof(ranges::elements_of, allocator>) == 1); #ifndef __EDG__ // TRANSITION, DevCom-10747012 static_assert(is_empty_v, allocator>>); From a6e682d5f1715dd2a107e94bc0c84c2f8de1eb49 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 20 Sep 2024 18:11:40 +0800 Subject: [PATCH 05/10] `ranges::` again --- .../GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp index d0c443ef647..a9bf3b07850 100644 --- a/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp +++ b/tests/std/tests/GH_001394_msvc_no_unique_address_23/test.compile.pass.cpp @@ -98,5 +98,5 @@ static_assert(sizeof(ranges::elements_of, pmr::polymorph static_assert(sizeof(ranges::elements_of, allocator>) == 1); #ifndef __EDG__ // TRANSITION, DevCom-10747012 -static_assert(is_empty_v, allocator>>); +static_assert(is_empty_v, allocator>>); #endif // ^^^ no workaround ^^^ From 53e042e7f733e3bc4aebd0314e76cab773a809a0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 20 Oct 2024 08:55:08 -0700 Subject: [PATCH 06/10] Extract TrivialAccessor to test_mdspan_support.hpp. --- tests/std/include/test_mdspan_support.hpp | 21 ++++++++++++++++++ .../std/tests/P0009R18_mdspan_mdspan/test.cpp | 21 ------------------ .../test.compile.pass.cpp | 22 ------------------- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/tests/std/include/test_mdspan_support.hpp b/tests/std/include/test_mdspan_support.hpp index 500d22be37a..d38af67a05d 100644 --- a/tests/std/include/test_mdspan_support.hpp +++ b/tests/std/include/test_mdspan_support.hpp @@ -175,6 +175,27 @@ constexpr bool check_accessor_policy_requirements() { return true; } +template +struct TrivialAccessor { + using offset_policy = TrivialAccessor; + using element_type = ElementType; + using reference = ElementType&; + using data_handle_type = ElementType*; + + constexpr reference access(data_handle_type handle, std::size_t off) const noexcept { + return handle[off]; + } + + constexpr data_handle_type offset(data_handle_type handle, std::size_t off) const noexcept { + return handle + off; + } + + int member; +}; + +static_assert(check_accessor_policy_requirements>()); +static_assert(std::is_trivial_v>); + namespace detail { template constexpr void check_members_with_mixed_extents(Fn&& fn) { diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index 9ed92972f99..a7765b97322 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -318,27 +318,6 @@ struct AccessorWithCustomOffsetPolicy { static_assert(check_accessor_policy_requirements>()); -template -struct TrivialAccessor { - using offset_policy = TrivialAccessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; - - constexpr reference access(data_handle_type handle, size_t off) const noexcept { - return handle[off]; - } - - constexpr data_handle_type offset(data_handle_type handle, size_t off) const noexcept { - return handle + off; - } - - int member; -}; - -static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivial_v>); - template class AccessorTemplate> constexpr void check_modeled_concepts_and_member_types() { using Accessor = AccessorTemplate; diff --git a/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp index 79d84bf48f9..47722245301 100644 --- a/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp +++ b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp @@ -11,28 +11,6 @@ using namespace std; -template -struct TrivialAccessor { - using offset_policy = TrivialAccessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; - - constexpr reference access(data_handle_type handle, size_t off) const noexcept { - return handle[off]; - } - - constexpr data_handle_type offset(data_handle_type handle, size_t off) const noexcept { - return handle + off; - } - - int member; -}; - -static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivial_v>); - - // When 'E::rank_dynamic()' is equal to 0 then 'is_empty_v' should be true static_assert(!is_empty_v>); static_assert(!is_empty_v>); From d3bad8eefc561b52285496844504573d1c0cbf81 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 20 Feb 2025 19:21:58 +0800 Subject: [PATCH 07/10] Stealth merge conflict on `TrivialAccessor` --- tests/std/include/test_mdspan_support.hpp | 3 ++- .../std/tests/P0009R18_mdspan_mdspan/test.cpp | 22 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/tests/std/include/test_mdspan_support.hpp b/tests/std/include/test_mdspan_support.hpp index d38af67a05d..a2f02b103ca 100644 --- a/tests/std/include/test_mdspan_support.hpp +++ b/tests/std/include/test_mdspan_support.hpp @@ -194,7 +194,8 @@ struct TrivialAccessor { }; static_assert(check_accessor_policy_requirements>()); -static_assert(std::is_trivial_v>); +static_assert(is_trivially_copyable_v>); +static_assert(is_trivially_default_constructible_v>); namespace detail { template diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index 1c933e9df1d..a36411d53e8 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -318,28 +318,6 @@ struct AccessorWithCustomOffsetPolicy { static_assert(check_accessor_policy_requirements>()); -template -struct TrivialAccessor { - using offset_policy = TrivialAccessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; - - constexpr reference access(data_handle_type handle, size_t off) const noexcept { - return handle[off]; - } - - constexpr data_handle_type offset(data_handle_type handle, size_t off) const noexcept { - return handle + off; - } - - int member; -}; - -static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivially_copyable_v>); -static_assert(is_trivially_default_constructible_v>); - template class AccessorTemplate> constexpr void check_modeled_concepts_and_member_types() { using Accessor = AccessorTemplate; From cc94f19dcb0b6e8091119679f117a0eb75ce128e Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 20 Feb 2025 19:45:40 +0800 Subject: [PATCH 08/10] Fixup wrong merging --- stl/inc/mdspan | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/stl/inc/mdspan b/stl/inc/mdspan index a30de06763e..605657bf4c1 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -1432,9 +1432,10 @@ private: noexcept(noexcept(_Accessor._Acc.access(_Ptr, static_cast(_Mapping._Map(_Indices...))))) { _STL_INTERNAL_STATIC_ASSERT(conjunction_v...>); #if _CONTAINER_DEBUG_LEVEL > 0 - _STL_VERIFY(this->_Map.extents()._Contains_multidimensional_index(make_index_sequence{}, _Indices...), - "mdspan subscript out of range; extents_type::index-cast(std::move(indices)) must be " - "a multidimensional index in extents() (N5001 [mdspan.mdspan.members]/3)."); + _STL_VERIFY( + _Mapping._Map.extents()._Contains_multidimensional_index(make_index_sequence{}, _Indices...), + "mdspan subscript out of range; extents_type::index-cast(std::move(indices)) must be a multidimensional " + "index in extents() (N5001 [mdspan.mdspan.members]/3)."); #endif return _Accessor._Acc.access(_Ptr, static_cast(_Mapping._Map(_Indices...))); From f99c7b49af940ad923cca1a2a6f088cd14480b4a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 20 Feb 2025 20:24:54 +0800 Subject: [PATCH 09/10] `std::` --- tests/std/include/test_mdspan_support.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/include/test_mdspan_support.hpp b/tests/std/include/test_mdspan_support.hpp index a2f02b103ca..e9706697bed 100644 --- a/tests/std/include/test_mdspan_support.hpp +++ b/tests/std/include/test_mdspan_support.hpp @@ -194,8 +194,8 @@ struct TrivialAccessor { }; static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivially_copyable_v>); -static_assert(is_trivially_default_constructible_v>); +static_assert(std::is_trivially_copyable_v>); +static_assert(std::is_trivially_default_constructible_v>); namespace detail { template From 42453642d011c9a401800984c13f622885aaba06 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 3 Mar 2025 12:24:35 -0800 Subject: [PATCH 10/10] Header and comment nitpicks. --- tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp index 47722245301..0d85c79d2be 100644 --- a/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp +++ b/tests/std/tests/P0009R18_mdspan_msabi/test.compile.pass.cpp @@ -3,7 +3,6 @@ // Tests MSVC STL specific behavior on ABI. -#include #include #include @@ -40,7 +39,7 @@ static_assert(is_empty_v>>); // * 'Mds::layout_type' is // * 'layout_left' or 'layout_right' and 'Mds::extents_type::rank_dynamic() == 0', or // * 'layout_stride' and 'Mds::extents_type::rank() == 0' -// then 'sizeof(Mds) == sizeof(void*)' (MSVC STL specific behavior). +// then 'sizeof(Mds) == sizeof(void*)'. static_assert(sizeof(mdspan, layout_left>) == sizeof(void*)); static_assert(sizeof(mdspan, layout_left>) > sizeof(void*)); static_assert(sizeof(mdspan, layout_left, TrivialAccessor>) > sizeof(void*));