This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Reuse certain cxx_eval_constant_expression results in cxx_eval_vec_init_1 (PR c++/70001)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Patrick Palka <patrick at parcs dot ath dot cx>
- Cc: Jason Merrill <jason at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 10 Mar 2016 19:39:57 +0100
- Subject: Re: [C++ PATCH] Reuse certain cxx_eval_constant_expression results in cxx_eval_vec_init_1 (PR c++/70001)
- Authentication-results: sourceware.org; auth=none
- References: <20160310170351 dot GX3017 at tucnak dot redhat dot com> <CA+C-WL8eUxA5qJs_0QEAn7uYNKZp9SmVj6EHEtfjkXNiYv3gfw at mail dot gmail dot com> <20160310173732 dot GZ3017 at tucnak dot redhat dot com> <20160310175649 dot GA3017 at tucnak dot redhat dot com> <CA+C-WL9RVV18=Qc4N1PgzwaZuG6LKHgLpmV0a2BfY=j+JSB0Bw at mail dot gmail dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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 <jakub@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