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.
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)
--- /dev/null
+// 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};
+}