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)

Reply via email to