[pushed] c++: c++20 constexpr default ctor and array init
Commit Message
The implicit constexpr patch revealed that marking the constructor in the
PR70690 testcase as constexpr made the bug reappear, because build_vec_init
assumed that a constexpr default constructor initialized the whole object,
so it was equivalent to value-initialization. But this is no longer true in
C++20.
Tested x86_64-pc-linux-gnu, applying to trunk.
PR c++/70690
gcc/cp/ChangeLog:
* init.c (build_vec_init): Check default_init_uninitialized_part in
C++20.
gcc/testsuite/ChangeLog:
* g++.dg/init/array41a.C: New test.
---
gcc/cp/init.c | 7 +++++--
gcc/testsuite/g++.dg/init/array41a.C | 27 +++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/init/array41a.C
base-commit: 4df7f8c79835d56928f51f9e674d326300936e8e
@@ -4470,11 +4470,14 @@ build_vec_init (tree base, tree maxindex, tree init,
We do need to keep going if we're copying an array. */
- if (try_const && !init)
+ if (try_const && !init
+ && (cxx_dialect < cxx20
+ || !default_init_uninitialized_part (inner_elt_type)))
/* With a constexpr default constructor, which we checked for when
setting try_const above, default-initialization is equivalent to
value-initialization, and build_value_init gives us something more
- friendly to maybe_constant_init. */
+ friendly to maybe_constant_init. Except in C++20 and up a constexpr
+ constructor need not initialize all the members. */
explicit_value_init_p = true;
if (from_array
|| ((type_build_ctor_call (type) || init || explicit_value_init_p)
new file mode 100644
@@ -0,0 +1,27 @@
+// PR c++/70690
+// { dg-do run { target c++11 } }
+
+struct A {
+ constexpr A() {}
+};
+
+struct APadded : public A {
+ char pad[63];
+};
+
+int f();
+int i = f();
+APadded cache[50];
+APadded *p = cache;
+
+int f()
+{
+ cache[0].pad[0] = 42;
+ return 1;
+}
+
+int main()
+{
+ if (cache[0].pad[0] != 42)
+ __builtin_abort();
+}