aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@gcc.gnu.org>2016-03-10 17:23:06 +0000
committerJakub Jelinek <jakub@gcc.gnu.org>2016-03-10 18:23:06 +0100
commitb87a8d7de708533d909b808a46d9fe52b7a07e52 (patch)
tree8be605f86954df50bdc1048c627cdac0526251e5 /gcc
parent48090169ea765dd56274dbc7863be562d14037a2 (diff)
downloadgcc-b87a8d7de708533d909b808a46d9fe52b7a07e52.zip
gcc-b87a8d7de708533d909b808a46d9fe52b7a07e52.tar.gz
gcc-b87a8d7de708533d909b808a46d9fe52b7a07e52.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/constexpr.c16
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-70001-1.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-70001-2.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-70001-3.C26
6 files changed, 88 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6e69e77..46174cc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 7f3edcf..5f97c9d 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c6ffcf3..3043ab9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-1.C
new file mode 100644
index 0000000..e68ff0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-1.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-2.C
new file mode 100644
index 0000000..96f5ad4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-2.C
@@ -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 ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-3.C
new file mode 100644
index 0000000..99d4c38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70001-3.C
@@ -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);
+}