diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-03-18 16:59:50 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-10-09 13:39:15 +0100 |
commit | 993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74 (patch) | |
tree | 0fbd52f636751a2242cb282a0476b187c38036c3 | |
parent | ce89d2f3170e0d6474cee2c5cb9d478426a5b2f6 (diff) | |
download | gcc-993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74.zip gcc-993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74.tar.gz gcc-993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74.tar.bz2 |
libstdc++: Make std::construct_at support arrays (LWG 3436)
The issue was approved at the recent St. Louis meeting, requiring
support for bounded arrays, but only without arguments to initialize the
array elements.
libstdc++-v3/ChangeLog:
* include/bits/stl_construct.h (construct_at): Support array
types (LWG 3436).
* testsuite/20_util/specialized_algorithms/construct_at/array.cc:
New test.
* testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc:
New test.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-opt1.C: Adjust for different diagnostics
from std::construct_at by adding -fconcepts-diagnostics-depth=2.
4 files changed, 78 insertions, 3 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C index 391b7c4..38c4f00 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C @@ -1,5 +1,6 @@ // PR c++/110102 // { dg-do compile { target c++11 } } +// { dg-additional-options "-fconcepts-diagnostics-depth=2" { target c++20 } } // { dg-skip-if "requires hosted libstdc++ for list" { ! hostedlib } } // { dg-error "deleted|construct_at" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index dc08fb7..146ea14 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -90,11 +90,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cpp_constexpr_dynamic_alloc // >= C++20 template<typename _Tp, typename... _Args> - constexpr auto + requires (!is_unbounded_array_v<_Tp>) + && requires { ::new((void*)0) _Tp(std::declval<_Args>()...); } + constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...))) - -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...)) - { return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); } + { + void* __loc = const_cast<remove_cv_t<_Tp>*>(__location); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3436. std::construct_at should support arrays + if constexpr (is_array_v<_Tp>) + { + static_assert(sizeof...(_Args) == 0, "std::construct_at for array " + "types must not use any arguments to initialize the " + "array"); + return ::new(__loc) _Tp[1](); + } + else + return ::new(__loc) _Tp(std::forward<_Args>(__args)...); + } #endif // C++20 #endif// C++17 diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc new file mode 100644 index 0000000..c368346 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc @@ -0,0 +1,41 @@ +// { dg-do compile { target c++20 } } + +// LWG 3436. std::construct_at should support arrays + +#include <memory> +#include <testsuite_hooks.h> + +constexpr void +test_array() +{ + int arr[1] { 99 }; + std::construct_at(&arr); + VERIFY( arr[0] == 0 ); + + union U { + long long x; + int arr[4]; + } u; + u.x = -1; + + auto p = std::construct_at(&u.arr); + VERIFY( (*p)[0] == 0 ); + VERIFY( (*p)[1] == 0 ); + VERIFY( (*p)[2] == 0 ); + VERIFY( (*p)[3] == 0 ); + + struct NonTrivial { + constexpr NonTrivial() : i(99) { } + int i; + }; + + union U2 { + char c = 'a'; + NonTrivial arr[2]; + } u2; + + auto p2 = std::construct_at(&u2.arr); + VERIFY( (*p2)[0].i == 99 ); +} + +static_assert( [] { test_array(); return true; }() ); diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc new file mode 100644 index 0000000..deb8693 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++20 } } + +// LWG 3436. std::construct_at should support arrays + +#include <memory> + +void +test_array_args() +{ + int arr[2]; + std::construct_at(&arr, 1, 2); // { dg-error "here" } + // { dg-error "must not use any arguments" "" { target *-*-* } 0 } +} + +void +test_unbounded_array(int (*p)[]) +{ + std::construct_at(p); // { dg-error "no matching function" } +} |