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.

From-SVN: r246858
This commit is contained in:
Jason Merrill 2017-04-11 17:07:32 -04:00 committed by Jason Merrill
parent 347e1f7769
commit 125db6a1c6
3 changed files with 30 additions and 5 deletions

View 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

View 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;
}

View File

@ -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;