PR c++/80294 - ICE with constexpr and inheritance.
authorJason Merrill <jason@redhat.com>
Tue, 11 Apr 2017 21:07:32 +0000 (17:07 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 11 Apr 2017 21:07:32 +0000 (17:07 -0400)
* constexpr.c (reduced_constant_expression_p):
A null constructor element is non-constant.
(cxx_eval_indirect_ref): Don't VERIFY_CONSTANT before
returning an empty base.

From-SVN: r246858

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

index c06b505..80247bf 100644 (file)
@@ -1,3 +1,11 @@
+2017-04-11  Jason Merrill  <jason@redhat.com>
+
+       PR c++/80294 - ICE with constexpr and inheritance.
+       * constexpr.c (reduced_constant_expression_p):
+       A null constructor element is non-constant.
+       (cxx_eval_indirect_ref): Don't VERIFY_CONSTANT before
+       returning an empty base.
+
 2017-04-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80370
index 3ca3560..9dde4a4 100644 (file)
@@ -1716,8 +1716,13 @@ reduced_constant_expression_p (tree t)
       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
       tree elt; unsigned HOST_WIDE_INT idx;
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt)
-       if (!reduced_constant_expression_p (elt))
-         return false;
+       {
+         if (!elt)
+           /* We're in the middle of initializing this element.  */
+           return false;
+         if (!reduced_constant_expression_p (elt))
+           return false;
+       }
       return true;
 
     default:
@@ -3153,12 +3158,10 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
   if (*non_constant_p)
     return t;
 
-  /* If we're pulling out the value of an empty base, make sure
-     that the whole object is constant and then return an empty
+  /* If we're pulling out the value of an empty base, just return an empty
      CONSTRUCTOR.  */
   if (empty_base && !lval)
     {
-      VERIFY_CONSTANT (r);
       r = build_constructor (TREE_TYPE (t), NULL);
       TREE_CONSTANT (r) = true;
     }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C
new file mode 100644 (file)
index 0000000..37e4a53
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/80294
+// { dg-do compile { target c++14 } }
+// { dg-final { scan-assembler-not "static_init" } }
+
+struct A {
+  constexpr int f() { A a = *this; return 42; }
+};
+struct B: A
+{
+  int i;
+  constexpr B(): i(f()) {}
+};
+
+B b;