From bd95d75f3412e1a7debab7c6c602ba409f274eb5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 11 Nov 2021 22:03:53 -0500 Subject: [PATCH] c++: c++20 constexpr default ctor and array init 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. 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 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 771a19b..3ba2e3b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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) diff --git a/gcc/testsuite/g++.dg/init/array41a.C b/gcc/testsuite/g++.dg/init/array41a.C new file mode 100644 index 0000000..aa9fdc6 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array41a.C @@ -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(); +} -- 2.7.4