aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-07-17 15:44:26 -0400
committerMarek Polacek <polacek@redhat.com>2024-07-31 08:49:53 -0400
commitbbc9c0423ca754e8e6ff80e08948ff52986337a0 (patch)
tree213957be23fb2063a9a66eb50c00fa20c14d8fe1
parentf40fd85c32c9ab4849065d0d14cd5a7ad67619b8 (diff)
downloadgcc-bbc9c0423ca754e8e6ff80e08948ff52986337a0.zip
gcc-bbc9c0423ca754e8e6ff80e08948ff52986337a0.tar.gz
gcc-bbc9c0423ca754e8e6ff80e08948ff52986337a0.tar.bz2
c++: array new with value-initialization, again [PR115645]
Unfortunately, my r15-1946 fix broke the attached testcase; the constexpr evaluation reported an error about not being able to evaluate the code emitted by build_vec_init. Jason figured out it's because we were wrongly setting try_const to false, where in fact it should have been true. Value-initialization of scalars is constexpr, so we should check that alongside of type_has_constexpr_default_constructor. PR c++/115645 gcc/cp/ChangeLog: * init.cc (build_vec_init): When initializing a scalar type, try to create a constant initializer. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-new23.C: New test.
-rw-r--r--gcc/cp/init.cc5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new23.C38
2 files changed, 42 insertions, 1 deletions
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index e9561c1..de82152 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -4724,7 +4724,10 @@ build_vec_init (tree base, tree maxindex, tree init,
&& TREE_CONSTANT (maxindex)
&& (init ? TREE_CODE (init) == CONSTRUCTOR
: (type_has_constexpr_default_constructor
- (inner_elt_type)))
+ (inner_elt_type)
+ /* Value-initialization of scalars is constexpr. */
+ || (explicit_value_init_p
+ && SCALAR_TYPE_P (inner_elt_type))))
&& (literal_type_p (inner_elt_type)
|| TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)));
vec<constructor_elt, va_gc> *const_vec = NULL;
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new23.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new23.C
new file mode 100644
index 0000000..1abbef1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new23.C
@@ -0,0 +1,38 @@
+// PR c++/115645
+// { dg-do compile { target c++20 } }
+
+using size_t = decltype(sizeof(0));
+
+void* operator new(size_t, void* p) { return p; }
+void* operator new[](size_t, void* p) { return p; }
+
+#define VERIFY(C) if (!(C)) throw
+
+namespace std {
+ template<typename T>
+ constexpr T* construct_at(T* p)
+ {
+ if constexpr (__is_array(T))
+ return ::new((void*)p) T[1]();
+ else
+ return ::new((void*)p) T();
+ }
+}
+
+constexpr void
+test_array()
+{
+ int arr[1] { 99 };
+ std::construct_at(&arr);
+ VERIFY( arr[0] == 0 );
+
+ union U {
+ long long x = -1;
+ int arr[4];
+ } u;
+
+ auto p = std::construct_at(&u.arr);
+ VERIFY( (*p)[0] == 0 );
+}
+
+static_assert( [] { test_array(); return true; }() );