]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/80294 - ICE with constexpr and inheritance.
authorJason Merrill <jason@redhat.com>
Mon, 18 Sep 2017 18:34:10 +0000 (14:34 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 Sep 2017 18:34:10 +0000 (14:34 -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: r252940

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

index 7cfae4e9563983920a5003f62b153ae223eaa1d9..fedfea7312a9240291248e8e10b0945c7d0e4a74 100644 (file)
@@ -1,5 +1,11 @@
 2017-09-18  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.
+
        PR c++/79607 - ICE with T{} initializer
        * decl.c (type_dependent_init_p): Check the type of a CONSTRUCTOR.
 
index 3f37cd50fcf293cf74491cc249b722f78776de58..4f23f754c04eea720d221b7361e4b26cb1d8f516 100644 (file)
@@ -1504,8 +1504,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:
@@ -2693,12 +2698,10 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree 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;