From 887bdabfe3e315d661bed55800cd4f64542c7029 Mon Sep 17 00:00:00 2001 From: Simon Martin <simon@nasilyan.com> Date: Tue, 4 Feb 2025 10:44:10 +0100 Subject: [PATCH] c++: Properly detect calls to digest_init in build_vec_init [PR114619] We currently ICE in checking mode with cxx_dialect < 17 on the following valid code === cut here === struct X { X(const X&) {} }; extern X x; void foo () { new X[1]{x}; } === cut here === We trip on a gcc_checking_assert in cp_gimplify_expr due to a TARGET_EXPR that is not TARGET_EXPR_ELIDING_P. As pointed by Jason, the problem is that build_vec_init does not recognize that digest_init has been called, and we end up calling the copy constructor twice. This happens because the detection in build_vec_init assumes that BASE is a reference to the array, while it's a pointer to its first element here. This patch makes sure that the detection works in both cases. PR c++/114619 gcc/cp/ChangeLog: * init.cc (build_vec_init): Properly determine whether digest_init has been called. gcc/testsuite/ChangeLog: * g++.dg/init/no-elide4.C: New test. --- gcc/cp/init.cc | 3 ++- gcc/testsuite/g++.dg/init/no-elide4.C | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/init/no-elide4.C diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 3ab7f96335c9..613775c5a7c8 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4786,7 +4786,8 @@ build_vec_init (tree base, tree maxindex, tree init, tree field, elt; /* If the constructor already has the array type, it's been through digest_init, so we shouldn't try to do anything more. */ - bool digested = same_type_p (atype, TREE_TYPE (init)); + bool digested = (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE + && same_type_p (type, TREE_TYPE (TREE_TYPE (init)))); from_array = 0; if (length_check) diff --git a/gcc/testsuite/g++.dg/init/no-elide4.C b/gcc/testsuite/g++.dg/init/no-elide4.C new file mode 100644 index 000000000000..9377d9f01611 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/no-elide4.C @@ -0,0 +1,11 @@ +// PR c++/114619 +// { dg-do "compile" { target c++11 } } +// { dg-options "-fno-elide-constructors" } + +struct X { + X(const X&) {} +}; +extern X x; +void foo () { + new X[1]{x}; +} -- GitLab