c++: Fix up maybe_init_list_as_array for RAW_DATA_CST [PR118124]
The previous patch made me look around some more and I found maybe_init_list_as_array doesn't handle RAW_DATA_CSTs correctly either, while the RAW_DATA_CST is properly split during finish_compound_literal, it was using CONSTRUCTOR_NELTS as the size of the arrays, which is wrong, RAW_DATA_CST could stand for far more initializers. 2025-01-15 Jakub Jelinek <jakub@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.
This commit is contained in:
parent
f263f2d525
commit
64828272cd
4 changed files with 45 additions and 5 deletions
|
@ -4331,6 +4331,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. */
|
||||
|
@ -4392,7 +4406,8 @@ maybe_init_list_as_array (tree elttype, tree init)
|
|||
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;
|
||||
|
@ -8801,7 +8816,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
|
|||
{
|
||||
/* 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))
|
||||
|
@ -8809,7 +8824,9 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
|
|||
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);
|
||||
|
|
|
@ -8179,7 +8179,7 @@ extern tree build_aggr_init_expr (tree, 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);
|
||||
|
|
|
@ -1207,7 +1207,7 @@ build_cplus_array_type (tree elt_type, tree index_type, int dependent)
|
|||
/* 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)));
|
||||
}
|
||||
|
|
23
gcc/testsuite/g++.dg/cpp0x/initlist-opt5.C
Normal file
23
gcc/testsuite/g++.dg/cpp0x/initlist-opt5.C
Normal file
|
@ -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 };
|
Loading…
Add table
Reference in a new issue