aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-03-18 16:59:50 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-10-09 13:39:15 +0100
commit993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74 (patch)
tree0fbd52f636751a2242cb282a0476b187c38036c3
parentce89d2f3170e0d6474cee2c5cb9d478426a5b2f6 (diff)
downloadgcc-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.
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C1
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h20
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc41
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc19
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" }
+}