]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/70001
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Mar 2016 17:23:06 +0000 (17:23 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Mar 2016 17:23:06 +0000 (17:23 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234117 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-70001-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/constexpr-70001-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/constexpr-70001-3.C [new file with mode: 0644]

index 6e69e77b5ca5c72c918dfb1b1308025c0dffa719..46174cc967a4143b6665f461aa2323ecc8d19b8d 100644 (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
index 7f3edcf431e9721aecba2cb2c4c79cee44032e95..5f97c9dad192bc0bc0ebe5380b85ec1b13f24872 100644 (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
        {
index c6ffcf3885373220429444a2966061861b9056c9..3043ab95b2257a3ed4d38dadcb1bbfc5e5f7b237 100644 (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
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 (file)
index 0000000..e68ff0e
--- /dev/null
@@ -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 (file)
index 0000000..96f5ad4
--- /dev/null
@@ -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 (file)
index 0000000..99d4c38
--- /dev/null
@@ -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);
+}