https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84281
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org, | |nathan at gcc dot gnu.org --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- The following makes it finish instantanously. I'm a bit worried about the assert in cxx_eval_store_expression which for ARRAY constructors asserts if (code == ARRAY_TYPE) { HOST_WIDE_INT i = find_array_ctor_elt (*valp, index, /*insert*/true); gcc_assert (i >= 0); cep = CONSTRUCTOR_ELT (*valp, i); gcc_assert (TREE_CODE (cep->index) != RANGE_EXPR); not sure if we need to handle RANGE_EXPR here (simply split the thing!). Jason/Nathan, can any of you pick this up please? This is an opportunity to save a lot of memory/compile-time for I guess quite common cases (no need to unshare all the elements nor allocate the index INTEGER_CSTs which is what gobbles up all the memory in this case...). I'll throw the patch to testing just in case - but double checking the above assert by you would be nice (not sure how we could ever end up storing into sth generated by cxx_eval_vec_init_1, but ...). Not sure how good testing coverage is in this area either. Index: gcc/cp/constexpr.c =================================================================== --- gcc/cp/constexpr.c (revision 257491) +++ gcc/cp/constexpr.c (working copy) @@ -2885,7 +2885,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype)); verify_ctor_sanity (ctx, atype); vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor); - vec_alloc (*p, max + 1); bool pre_init = false; unsigned HOST_WIDE_INT i; @@ -2978,13 +2977,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; - for (i = 1; i < max; ++i) - { - idx = build_int_cst (size_type_node, i); - CONSTRUCTOR_APPEND_ELT (*p, idx, unshare_constructor (eltinit)); - } + tree range = build2 (RANGE_EXPR, size_type_node, + build_int_cst (size_type_node, 1), + build_int_cst (size_type_node, max - 1)); + CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit)); break; } + else + vec_safe_reserve (*p, max + 1); } if (!*non_constant_p)