PR c++/87075 - ICE with constexpr array initialization.
authorJason Merrill <jason@redhat.com>
Thu, 20 Sep 2018 17:09:19 +0000 (13:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 20 Sep 2018 17:09:19 +0000 (13:09 -0400)
My patch of 2016-08-26 to avoid calling a trivial default constructor
introduced TARGET_EXPRs initialized with void_node to express trivial
initialization.  But when this shows up in a VEC_INIT_EXPR, we weren't
prepared to handle it.  Fixed by handling it explicitly in
cxx_eval_vec_init_1.

* constexpr.c (cxx_eval_vec_init_1): Handle trivial initialization.

From-SVN: r264442

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp1y/constexpr-array6.C [new file with mode: 0644]

index 75286d53fdba361d43849aaf643e7409b1f78958..c5072d53334d60fd344fdf2093e3cc9562765e60 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/87075 - ICE with constexpr array initialization.
+       * constexpr.c (cxx_eval_vec_init_1): Handle trivial initialization.
+
 2018-09-19  Marek Polacek  <polacek@redhat.com>
 
        Add -Wclass-conversion.
index aa33319875fcad1cd87fefbb802e46dd0706a5f2..fdea769faa99d8b179d0953541be669a03f8b92c 100644 (file)
@@ -3034,6 +3034,9 @@ 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.  */
+         if (init == void_node)
+           /* Trivial default-init, don't do anything to the CONSTRUCTOR.  */
+           return ctx->ctor;
          eltinit = cxx_eval_constant_expression (&new_ctx, init, lval,
                                                  non_constant_p, overflow_p);
          reuse = i == 0;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-array6.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-array6.C
new file mode 100644 (file)
index 0000000..1f15bef
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/87075
+// { dg-do compile { target c++14 } }
+
+template <typename T>
+struct vec
+{
+  struct { T y; } n;
+  vec() = default;
+};
+
+template <typename T>
+struct S
+{
+  vec<T> value[2];
+  template<typename U>
+  constexpr S(const U&);
+};
+
+template<typename T>
+template<typename X>
+constexpr S<T>::S(const X&)
+{
+  value[0] = vec<T>();
+}
+
+S<float>m(0);