On Thu, Mar 10, 2016 at 01:32:10PM -0500, Patrick Palka wrote:
> Looks fine to me :)

On a closer look, this doesn't handle the multi-dimensional array cases,
and even for single-dimensional ones will not share the CONSTRUCTOR
if init_subob_ctx created one, and call init_subob_ctx many times
and in there in some cases e.g. build new new_ctx.object every time etc.

Is this also ok, if it passes bootstrap/regtest?

2016-03-10  Jakub Jelinek  <ja...@redhat.com>

        PR c++/70001
        * constexpr.c (cxx_eval_vec_init_1): Reuse CONSTRUCTOR initializers
        for 1..max even for multi-dimensional arrays, and reuse not just
        eltinit itself, but surrounding subobject CONSTRUCTOR too.

        * g++.dg/cpp0x/constexpr-70001-4.C: New test.

--- gcc/cp/constexpr.c.jj       2016-03-10 12:52:04.000000000 +0100
+++ gcc/cp/constexpr.c  2016-03-10 19:24:28.435537864 +0100
@@ -2340,7 +2340,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx
   vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
   vec_alloc (*p, max + 1);
   bool pre_init = false;
-  tree pre_init_elt = NULL_TREE;
   unsigned HOST_WIDE_INT i;
 
   /* For the default constructor, build up a call to the default
@@ -2370,6 +2369,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx
     {
       tree idx = build_int_cst (size_type_node, i);
       tree eltinit;
+      bool reuse = false;
       constexpr_ctx new_ctx;
       init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
       if (new_ctx.ctor != ctx->ctor)
@@ -2378,7 +2378,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx
        {
          /* A multidimensional array; recurse.  */
          if (value_init || init == NULL_TREE)
-           eltinit = NULL_TREE;
+           {
+             eltinit = NULL_TREE;
+             reuse = i == 0;
+           }
          else
            eltinit = cp_build_array_ref (input_location, init, idx,
                                          tf_warning_or_error);
@@ -2390,18 +2393,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx
        {
          /* Initializing an element using value or default initialization
             we just pre-built above.  */
-         if (pre_init_elt == NULL_TREE)
-           pre_init_elt
-             = cxx_eval_constant_expression (&new_ctx, init, lval,
-                                             non_constant_p, overflow_p);
-         eltinit = pre_init_elt;
-         /* Don't reuse the result of cxx_eval_constant_expression
-            call if it isn't a constant initializer or if it requires
-            relocations.  */
-         if (initializer_constant_valid_p (pre_init_elt,
-                                           TREE_TYPE (pre_init_elt))
-             != null_pointer_node)
-           pre_init_elt = NULL_TREE;
+         eltinit = cxx_eval_constant_expression (&new_ctx, init, lval,
+                                                 non_constant_p, overflow_p);
+         reuse = i == 0;
        }
       else
        {
@@ -2427,6 +2421,23 @@ cxx_eval_vec_init_1 (const constexpr_ctx
        }
       else
        CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
+      /* Don't reuse the result of cxx_eval_constant_expression
+        call if it isn't a constant initializer or if it requires
+        relocations.  */
+      if (reuse
+         && max > 1
+         && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
+             == null_pointer_node))
+       {
+         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, eltinit);
+           }
+         break;
+       }
     }
 
   if (!*non_constant_p)
--- gcc/testsuite/g++.dg/cpp0x/constexpr-70001-4.C.jj   2016-03-10 
19:28:13.386481311 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-70001-4.C      2016-03-10 
19:28:43.295074924 +0100
@@ -0,0 +1,13 @@
+// PR c++/70001
+// { dg-do compile { target c++11 } }
+
+struct B
+{
+  int a;
+  constexpr B () : a (0) { }
+};
+
+struct A
+{
+  B b[1 << 19][1][1][1];
+} c;


        Jakub

Reply via email to