re PR c++/70001 (Infinity compilation time)

PR c++/70001
	* constexpr.c (cxx_eval_vec_init_1): For pre_init case, reuse
	return value from cxx_eval_constant_expression from earlier
	elements if it is valid constant initializer requiring no
	relocations.

	* g++.dg/cpp0x/constexpr-70001-1.C: New test.
	* g++.dg/cpp0x/constexpr-70001-2.C: New test.
	* g++.dg/cpp0x/constexpr-70001-3.C: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r234117
This commit is contained in:
Patrick Palka 2016-03-10 17:23:06 +00:00 committed by Jakub Jelinek
parent 48090169ea
commit b87a8d7de7
6 changed files with 88 additions and 3 deletions

View file

@ -1,3 +1,12 @@
2016-03-10 Patrick Palka <ppalka@gcc.gnu.org>
Jakub Jelinek <jakub@redhat.com>
PR c++/70001
* constexpr.c (cxx_eval_vec_init_1): For pre_init case, reuse
return value from cxx_eval_constant_expression from earlier
elements if it is valid constant initializer requiring no
relocations.
2016-03-10 Marek Polacek <polacek@redhat.com>
PR c++/70153

View file

@ -2340,6 +2340,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
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
@ -2389,9 +2390,18 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
{
/* Initializing an element using value or default initialization
we just pre-built above. */
eltinit = (cxx_eval_constant_expression
(&new_ctx, init,
lval, non_constant_p, overflow_p));
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;
}
else
{

View file

@ -1,3 +1,11 @@
2016-03-10 Patrick Palka <ppalka@gcc.gnu.org>
Jakub Jelinek <jakub@redhat.com>
PR c++/70001
* g++.dg/cpp0x/constexpr-70001-1.C: New test.
* g++.dg/cpp0x/constexpr-70001-2.C: New test.
* g++.dg/cpp0x/constexpr-70001-3.C: New test.
2016-03-10 Jan Hubicka <hubicka@ucw.cz>
PR lto/69589

View file

@ -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];
} c;

View file

@ -0,0 +1,19 @@
// PR c++/70001
// { dg-do run { target c++11 } }
struct B
{
struct B *a;
constexpr B () : a (this) { }
};
constexpr int N = 1 << 4;
struct A { B c[N]; } d;
int
main ()
{
for (int i = 0; i < N; ++i)
if (d.c[i].a != &d.c[i])
__builtin_abort ();
}

View file

@ -0,0 +1,26 @@
// PR c++/70001
// { dg-do compile { target c++11 } }
#include <array>
#include <complex>
typedef std::complex<double> cd;
const int LOG = 17;
const int N = (1 << LOG);
std::array<cd, N> a;
std::array<cd, N> b;
void
foo (std::array<cd, N> &arr)
{
std::array<std::array<cd, N>, LOG + 1> f;
}
int
main ()
{
foo (a);
foo (b);
}