2024-12-19 Jakub Jelinek <ja...@redhat.com>
PR c++/118124
* cp-tree.h (build_array_of_n_type): Change second argument type
from int to unsigned HOST_WIDE_INT.
* tree.cc (build_array_of_n_type): Likewise.
* call.cc (count_ctor_elements): New function.
(maybe_init_list_as_array): Use it instead of CONSTRUCTOR_NELTS.
(convert_like_internal): Use length from init's type instead of
len when handling the maybe_init_list_as_array case.
* g++.dg/cpp0x/initlist-opt5.C: New test.
--- gcc/cp/cp-tree.h.jj 2024-12-19 18:47:01.444498895 +0100
+++ gcc/cp/cp-tree.h 2024-12-19 19:12:10.252716265 +0100
@@ -8156,7 +8156,7 @@ extern tree build_aggr_init_expr (tree,
extern tree get_target_expr (tree,
tsubst_flags_t =
tf_warning_or_error);
extern tree build_cplus_array_type (tree, tree, int is_dep = -1);
-extern tree build_array_of_n_type (tree, int);
+extern tree build_array_of_n_type (tree, unsigned HOST_WIDE_INT);
extern bool array_of_runtime_bound_p (tree);
extern bool vla_type_p (tree);
extern tree build_array_copy (tree);
--- gcc/cp/tree.cc.jj 2024-12-19 11:35:59.227312977 +0100
+++ gcc/cp/tree.cc 2024-12-19 19:12:34.291385303 +0100
@@ -1207,7 +1207,7 @@ build_cplus_array_type (tree elt_type, t
/* Return an ARRAY_TYPE with element type ELT and length N. */
tree
-build_array_of_n_type (tree elt, int n)
+build_array_of_n_type (tree elt, unsigned HOST_WIDE_INT n)
{
return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
}
--- gcc/cp/call.cc.jj 2024-12-19 18:50:52.478315892 +0100
+++ gcc/cp/call.cc 2024-12-19 19:13:15.528817544 +0100
@@ -4325,6 +4325,20 @@ has_non_trivial_temporaries (tree expr)
return false;
}
+/* Return number of initialized elements in CTOR. */
+
+static unsigned HOST_WIDE_INT
+count_ctor_elements (tree ctor)
+{
+ unsigned HOST_WIDE_INT len = 0;
+ for (constructor_elt &e: CONSTRUCTOR_ELTS (ctor))
+ if (TREE_CODE (e.value) == RAW_DATA_CST)
+ len += RAW_DATA_LENGTH (e.value);
+ else
+ ++len;
+ return len;
+}
+
/* We're initializing an array of ELTTYPE from INIT. If it seems useful,
return INIT as an array (of its own type) so the caller can initialize the
target array in a loop. */
@@ -4386,7 +4400,8 @@ maybe_init_list_as_array (tree elttype,
if (!is_xible (INIT_EXPR, elttype, copy_argtypes))
return NULL_TREE;
- tree arr = build_array_of_n_type (init_elttype, CONSTRUCTOR_NELTS (init));
+ unsigned HOST_WIDE_INT len = count_ctor_elements (init);
+ tree arr = build_array_of_n_type (init_elttype, len);
arr = finish_compound_literal (arr, init, tf_none);
DECL_MERGEABLE (TARGET_EXPR_SLOT (arr)) = true;
return arr;
@@ -8761,14 +8776,16 @@ convert_like_internal (conversion *convs
{
/* Conversion to std::initializer_list<T>. */
tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
- unsigned len = CONSTRUCTOR_NELTS (expr);
+ unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (expr);
tree array;
if (tree init = maybe_init_list_as_array (elttype, expr))
{
elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype)
| TYPE_QUAL_CONST);
- array = build_array_of_n_type (elttype, len);
+ tree index_type = TYPE_DOMAIN (TREE_TYPE (init));
+ array = build_cplus_array_type (elttype, index_type);
+ len = TREE_INT_CST_LOW (TYPE_MAX_VALUE (index_type)) + 1;
array = build_vec_init_expr (array, init, complain);
array = get_target_expr (array);
array = cp_build_addr_expr (array, complain);
--- gcc/testsuite/g++.dg/cpp0x/initlist-opt5.C.jj 2024-12-19
19:07:28.725592353 +0100
+++ gcc/testsuite/g++.dg/cpp0x/initlist-opt5.C 2024-12-19 19:07:28.725592353
+0100
@@ -0,0 +1,23 @@
+// PR c++/118124
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+
+namespace std {
+template <class T> struct initializer_list {
+private:
+ const T *_M_array;
+ decltype (sizeof 0) _M_len;
+};
+}
+struct B {
+ B (int);
+};
+struct A {
+ A (std::initializer_list<B>);
+};
+A a { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
Jakub